Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWalter Bender <walter.bender@gmail.com>2012-05-08 12:22:19 (GMT)
committer Walter Bender <walter.bender@gmail.com>2012-05-08 12:22:19 (GMT)
commitee39c04deb56799d0c20cbfd9c32886236ea3e7f (patch)
treed944450d7200f834bf5dadc26cd5aa6d366ac380
parentfaeb13e4533ec5a13ced04a27f67f900e5b02210 (diff)
sync with TurtleBlocks 139
-rw-r--r--NEWS8
-rw-r--r--TurtleArt/sprites.py30
-rw-r--r--TurtleArt/tabasics.py8
-rw-r--r--TurtleArt/tablock.py2
-rw-r--r--TurtleArt/tacanvas.py313
-rw-r--r--TurtleArt/taconstants.py13
-rw-r--r--TurtleArt/tagplay.py3
-rw-r--r--TurtleArt/talogo.py53
-rw-r--r--TurtleArt/tapalette.py114
-rwxr-xr-xTurtleArt/tasprite_factory.py25
-rw-r--r--TurtleArt/taturtle.py6
-rw-r--r--TurtleArt/tautils.py16
-rw-r--r--TurtleArt/tawindow.py240
-rw-r--r--TurtleConfusionActivity.py20
-rw-r--r--activity/activity.info2
-rw-r--r--images/help1200.svg50
-rw-r--r--images/palettehshift.svg86
-rw-r--r--images/palettevshift.svg86
-rw-r--r--images/print1200.svg50
-rw-r--r--images/status1200.svg80
-rw-r--r--po/TurtleConfusion.pot1519
-rwxr-xr-xturtleconfusion.py96
-rw-r--r--util/helpbutton.py118
23 files changed, 2272 insertions, 666 deletions
diff --git a/NEWS b/NEWS
index d64e5d2..db575ab 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,12 @@
+10
+
+ENHANCEMENTS
+* Added help for all levels
+* Sync up with Turtle Blocks 139
+* New translations
+
9
+
ENHANCEMENTS
* Added new help files written by Ignacio Rodriguez
* Sync with current Turtle Blocks
diff --git a/TurtleArt/sprites.py b/TurtleArt/sprites.py
index fdf0105..c400d88 100644
--- a/TurtleArt/sprites.py
+++ b/TurtleArt/sprites.py
@@ -83,6 +83,7 @@ import pango
import pangocairo
import cairo
+
class Sprites:
''' A class for the list of sprites and everything they share in common '''
@@ -130,12 +131,12 @@ class Sprites:
if spr in self.list:
self.list.remove(spr)
- def find_sprite(self, pos):
+ def find_sprite(self, pos, region=False):
''' Search based on (x, y) position. Return the 'top/first' one. '''
list = self.list[:]
list.reverse()
for spr in list:
- if spr.hit(pos):
+ if spr.hit(pos, readpixel=not region):
return spr
return None
@@ -350,7 +351,7 @@ class Sprite:
if len(self.labels) > 0:
self.draw_label(cr)
- def hit(self, pos):
+ def hit(self, pos, readpixel=False):
''' Is (x, y) on top of the sprite? '''
x, y = pos
if x < self.rect.x:
@@ -361,6 +362,12 @@ class Sprite:
return False
if y > self.rect.y + self.rect.height:
return False
+ if readpixel:
+ r, g, b, a = self.get_pixel(pos)
+ if r == g == b == a == 0:
+ return False
+ if a == -1:
+ return False
return self._sprites.find_in_list(self)
def draw_label(self, cr):
@@ -396,14 +403,14 @@ class Sprite:
x = int(self.rect.x + self._margins[0] + (my_width - w) / 2)
elif self._horiz_align[i] == 'left':
x = int(self.rect.x + self._margins[0])
- else: # right
+ else: # right
x = int(self.rect.x + self.rect.width - w - self._margins[2])
h = pl.get_size()[1] / pango.SCALE
if self._vert_align[i] == "middle":
y = int(self.rect.y + self._margins[1] + (my_height - h) / 2)
elif self._vert_align[i] == "top":
y = int(self.rect.y + self._margins[1])
- else: # bottom
+ else: # bottom
y = int(self.rect.y + self.rect.height - h - self._margins[3])
cr.save()
cr.translate(x, y)
@@ -448,16 +455,13 @@ class Sprite:
if x < 0 or x > (self.rect.width - 1) or \
y < 0 or y > (self.rect.height - 1):
return(-1, -1, -1, -1)
-
- # create a new 1x1 cairo surface
- cs = cairo.ImageSurface(cairo.FORMAT_RGB24, 1, 1);
+ # Create a new 1x1 cairo surface.
+ cs = cairo.ImageSurface(cairo.FORMAT_RGB24, 1, 1)
cr = cairo.Context(cs)
cr.set_source_surface(self.cached_surfaces[i], -x, -y)
- cr.rectangle(0,0,1,1)
+ cr.rectangle(0, 0, 1, 1)
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.fill()
- cs.flush() # ensure all writing is done
- # Read the pixel
- pixels = cs.get_data()
+ cs.flush() # Ensure all the writing is done.
+ pixels = cs.get_data() # Read the pixel.
return (ord(pixels[2]), ord(pixels[1]), ord(pixels[0]), 0)
-
diff --git a/TurtleArt/tabasics.py b/TurtleArt/tabasics.py
index 60b8d91..cf309cd 100644
--- a/TurtleArt/tabasics.py
+++ b/TurtleArt/tabasics.py
@@ -553,6 +553,7 @@ tasetshade :shade \r')
style='number-style',
label='+',
special_name=_('plus'),
+ string_or_number=True,
prim_name='plus',
logo_command='sum',
help_string=_('adds two alphanumeric inputs'))
@@ -662,6 +663,7 @@ operators'))
style='compare-porch-style',
label='>',
special_name=_('greater than'),
+ string_or_number=True,
prim_name='greater?',
logo_command='greater?',
help_string=_('logical greater-than operator'))
@@ -678,6 +680,7 @@ operators'))
style='compare-porch-style',
label='<',
special_name=_('less than'),
+ string_or_number=True,
prim_name='less?',
logo_command='less?',
help_string=_('logical less-than operator'))
@@ -692,6 +695,7 @@ operators'))
hidden=True,
style='compare-style',
label='=',
+ string_or_number=True,
special_name=_('equal'),
prim_name='equal?',
logo_command='equal?',
@@ -899,6 +903,7 @@ buttons'))
style='number-style-1strarg',
label=_('box'),
prim_name='box',
+ string_or_number=True,
default=_('my box'),
logo_command='box',
help_string=_('named variable (numeric value)'))
@@ -909,6 +914,7 @@ buttons'))
hidden=True,
style='basic-style-2arg',
label=[_('store in'), _('box'), _('value')],
+ string_or_number=True,
prim_name='storeinbox',
logo_command='storeinbox',
default=[_('my box'), 100],
@@ -923,6 +929,7 @@ variable'))
style='basic-style-head-1arg',
label=_('action'),
prim_name='nop3',
+ string_or_number=True,
default=_('action'),
logo_command='to action',
help_string=_('top of nameable action stack'))
@@ -949,6 +956,7 @@ variable'))
hidden=True,
style='basic-style-1arg',
label=_('action'),
+ string_or_number=True,
prim_name='stack',
logo_command='action',
default=_('action'),
diff --git a/TurtleArt/tablock.py b/TurtleArt/tablock.py
index b809930..f835994 100644
--- a/TurtleArt/tablock.py
+++ b/TurtleArt/tablock.py
@@ -512,7 +512,7 @@ class Block:
if self.name in BOX_COLORS:
self.colors = BOX_COLORS[self.name]
elif self.name in special_block_colors:
- self.colors = special_block_colors[self.name]
+ self.colors = special_block_colors[self.name]
else:
for p in range(len(palette_blocks)):
if self.name in palette_blocks[p]:
diff --git a/TurtleArt/tacanvas.py b/TurtleArt/tacanvas.py
index bf22248..6a78a17 100644
--- a/TurtleArt/tacanvas.py
+++ b/TurtleArt/tacanvas.py
@@ -73,7 +73,8 @@ def calc_gray(c, g, invert=False):
colors = {}
-DEGTOR = 2 * pi / 360
+DEGTOR = pi / 180.
+RTODEG = 180. / pi
COLOR_TABLE = (
0xFF0000, 0xFF0D00, 0xFF1A00, 0xFF2600, 0xFF3300,
@@ -106,12 +107,12 @@ class TurtleGraphics:
self.tw = tw
self.width = width
self.height = height
-
+
# Build a cairo.Context from a cairo.XlibSurface
self.canvas = cairo.Context(self.tw.turtle_canvas)
cr = gtk.gdk.CairoContext(self.canvas)
cr.set_line_cap(1) # Set the line cap to be round
-
+ self.cr_svg = None # Surface used for saving to SVG
self.cx = 0
self.cy = 0
self.fgrgb = [255, 0, 0]
@@ -127,16 +128,24 @@ class TurtleGraphics:
self.gray = 100
self.fill = False
self.poly_points = []
- self.svg = SVG()
- self.svg.set_fill_color('none')
- self.tw.svg_string = ''
+
+ def setup_svg_surface(self):
+ ''' Set up a surface for saving to SVG '''
+ if self.tw.running_sugar:
+ svg_surface = cairo.SVGSurface(
+ os.path.join(get_path(self.tw.activity, 'instance'),
+ 'output.svg'), self.width, self.height)
+ else:
+ svg_surface = cairo.SVGSurface(
+ os.path.join(os.getcwd(), 'output.svg'),
+ self.width, self.height)
+ 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 = []
- if self.tw.saving_svg:
- self.tw.svg_string += '<g>'
def stop_fill(self):
''' Fill the polygon. '''
@@ -153,52 +162,48 @@ class TurtleGraphics:
shared_poly_points]))
self.tw.send_event(event)
self.poly_points = []
- if self.tw.saving_svg:
- self.tw.svg_string += '</g>'
def fill_polygon(self, poly_points):
''' Draw the polygon... '''
- self.canvas.new_path()
- for i, p in enumerate(poly_points):
- if p[0] == 'move':
- self.canvas.move_to(p[1], p[2])
- elif p[0] == 'rarc':
- self.canvas.arc(p[1], p[2], p[3], p[4], p[5])
- elif p[0] == 'larc':
- self.canvas.arc_negative(p[1], p[2], p[3], p[4], p[5])
- else: # line
- self.canvas.line_to(p[1], p[2])
- self.canvas.close_path()
- self.canvas.fill()
- if self.tw.saving_svg and self.pendown:
- self.svg.set_fill_color('#%02x%02x%02x' % (self.fgrgb[0],
- self.fgrgb[1],
- self.fgrgb[2]))
- self.tw.svg_string += self.svg.new_path(poly_points[0][0],
- poly_points[0][1])
- for p in range(len(poly_points)):
- if p > 0:
- self.tw.svg_string += self.svg.line_to(poly_points[p][0],
- poly_points[p][1])
- self.tw.svg_string += '"\n'
- self.tw.svg_string += self.svg.style()
- self.svg.set_fill_color('none')
+ def _fill_polygon(cr, poly_points):
+ cr.new_path()
+ for i, p in enumerate(poly_points):
+ if p[0] == 'move':
+ cr.move_to(p[1], p[2])
+ elif p[0] == 'rarc':
+ cr.arc(p[1], p[2], p[3], p[4], p[5])
+ elif p[0] == 'larc':
+ cr.arc_negative(p[1], p[2], p[3], p[4], p[5])
+ else: # line
+ cr.line_to(p[1], p[2])
+ cr.close_path()
+ cr.fill()
+
+ _fill_polygon(self.canvas, poly_points)
+ self.inval()
+ if self.cr_svg is not None:
+ _fill_polygon(self.cr_svg, poly_points)
def clearscreen(self, share=True):
'''Clear the canvas and reset most graphics attributes to defaults.'''
- self.canvas.move_to(0, 0)
- self.canvas.set_source_rgb(self.bgrgb[0] / 255.,
- self.bgrgb[1] / 255.,
- self.bgrgb[2] / 255.)
- self.canvas.rectangle(0, 0, self.width * 2, self.height * 2)
- self.canvas.fill()
+
+ def _clearscreen(cr):
+ cr.move_to(0, 0)
+ cr.set_source_rgb(self.bgrgb[0] / 255.,
+ self.bgrgb[1] / 255.,
+ self.bgrgb[2] / 255.)
+ cr.rectangle(0, 0, self.width * 2, self.height * 2)
+ cr.fill()
+
+ _clearscreen(self.canvas)
self.inval()
+ 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.tw.svg_string = ''
- self.svg.reset_min_max()
self.fill = False
self.poly_points = []
for turtle_key in iter(self.tw.turtles.dict):
@@ -222,6 +227,10 @@ class TurtleGraphics:
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)
@@ -274,6 +283,9 @@ class TurtleGraphics:
''' 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)
@@ -303,11 +315,15 @@ class TurtleGraphics:
cy = self.ycor - r * sin(self.heading * DEGTOR)
if self.pendown:
x, y = self.turtle_to_screen_coordinates(cx, cy)
- self.canvas.arc(x, y, r,
- (self.heading - 180) * DEGTOR,
- (self.heading - 180 + a) * DEGTOR)
- self.canvas.stroke()
+
+ 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 == []:
@@ -319,13 +335,6 @@ class TurtleGraphics:
self.right(a, False)
self.xcor = cx - r * cos(self.heading * DEGTOR)
self.ycor = cy + r * sin(self.heading * DEGTOR)
- if self.tw.saving_svg and self.pendown:
- x, y = self.turtle_to_screen_coordinates(oldx, oldy)
- self.tw.svg_string += self.svg.new_path(x, y)
- x, y = self.turtle_to_screen_coordinates(self.xcor, self.ycor)
- self.tw.svg_string += self.svg.arc_to(x, y, r, a, 0, s)
- self.tw.svg_string += '"\n'
- self.tw.svg_string += self.svg.style()
def larc(self, a, r):
''' draw a counter-clockwise arc '''
@@ -341,11 +350,15 @@ class TurtleGraphics:
cy = self.ycor + r * sin(self.heading * DEGTOR)
if self.pendown:
x, y = self.turtle_to_screen_coordinates(cx, cy)
- self.canvas.arc_negative(x, y, r,
- (self.heading) * DEGTOR,
- (self.heading - a) * DEGTOR)
- self.canvas.stroke()
+
+ 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 == []:
@@ -357,13 +370,6 @@ class TurtleGraphics:
self.right(-a, False)
self.xcor = cx + r * cos(self.heading * DEGTOR)
self.ycor = cy - r * sin(self.heading * DEGTOR)
- if self.tw.saving_svg and self.pendown:
- x, y = self.turtle_to_screen_coordinates(oldx, oldy)
- self.tw.svg_string += self.svg.new_path(x, y)
- x, y = self.turtle_to_screen_coordinates(self.xcor, self.ycor)
- self.tw.svg_string += self.svg.arc_to(x, y, r, a, 0, s)
- self.tw.svg_string += '"\n'
- self.tw.svg_string += self.svg.style()
def setxy(self, x, y, share=True, pendown=True):
''' Move turtle to position x,y '''
@@ -381,6 +387,10 @@ class TurtleGraphics:
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()
@@ -402,7 +412,8 @@ class TurtleGraphics:
return
self.tw.active_turtle.set_pen_size(ps)
self.canvas.set_line_width(ps)
- self.svg.set_stroke_width(self.pensize)
+ 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)]))
@@ -478,17 +489,19 @@ class TurtleGraphics:
oldc, olds = self.color, self.shade
self.setcolor(c, False)
self.setshade(s, False)
- self.canvas.set_source_rgb(self.fgrgb[0] / 255.,
- self.fgrgb[1] / 255.,
- self.fgrgb[2] / 255.)
self.bgrgb = self.fgrgb[:]
- self.canvas.rectangle(0, 0, self.width * 2, self.height * 2)
- self.canvas.fill()
+
+ def _fillscreen(cr, rgb, w, h):
+ cr.set_source_rgb(rgb[0] / 255., rgb[1] / 255., rgb[2] / 255.)
+ cr.rectangle(0, 0, w * 2, h * 2)
+ cr.fill()
+
+ _fillscreen(self.canvas, self.fgrgb, self.width, self.height)
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.tw.svg_string = ''
- self.svg.reset_min_max()
self.fill = False
self.poly_points = []
@@ -515,9 +528,6 @@ class TurtleGraphics:
b = calc_gray(b, self.gray)
b = calc_shade(b, sh)
self.fgrgb = [r >> 8, g >> 8, b >> 8]
- self.svg.set_stroke_color('#%02x%02x%02x' % (self.fgrgb[0],
- self.fgrgb[1],
- self.fgrgb[2]))
def setpen(self, bool, share=True):
''' Lower or raise the pen '''
@@ -529,42 +539,39 @@ class TurtleGraphics:
def draw_surface(self, surface, x, y, w, h):
''' Draw a surface '''
- cr = gtk.gdk.CairoContext(self.canvas)
- cr.set_source_surface(surface, x, y)
- cr.rectangle(x, y, w, h)
- cr.fill()
+
+ def _draw_surface(cr, surface, x, y, w, h):
+ cc = gtk.gdk.CairoContext(cr)
+ cc.set_source_surface(surface, x, y)
+ cc.rectangle(x, y, w, h)
+ cc.fill()
+
+ _draw_surface(self.canvas, surface, x, y, w, h)
self.inval()
+ if self.cr_svg is not None:
+ _draw_surface(self.cr_svg, surface, x, y, w, h)
def draw_pixbuf(self, pixbuf, a, b, x, y, w, h, path, share=True):
''' Draw a pixbuf '''
- # Build a gtk.gdk.CairoContext from a cairo.Context to access
- # the set_source_pixbuf attribute.
- cr = gtk.gdk.CairoContext(self.canvas)
- cr.save()
- # center the rotation on the center of the image
- cr.translate(x + w / 2., y + h / 2.)
- cr.rotate(self.heading * DEGTOR)
- cr.translate(-x - w / 2., -y - h / 2.)
- cr.set_source_pixbuf(pixbuf, x, y)
- cr.rectangle(x, y, w, h)
- cr.fill()
- cr.restore()
+
+ def _draw_pixbuf(cr, pixbuf, a, b, x, y, w, h, heading):
+ # Build a gtk.gdk.CairoContext from a cairo.Context to access
+ # the set_source_pixbuf attribute.
+ cc = gtk.gdk.CairoContext(cr)
+ cc.save()
+ # center the rotation on the center of the image
+ cc.translate(x + w / 2., y + h / 2.)
+ cc.rotate(heading * DEGTOR)
+ cc.translate(-x - w / 2., -y - h / 2.)
+ cc.set_source_pixbuf(pixbuf, x, y)
+ cc.rectangle(x, y, w, h)
+ cc.fill()
+ cc.restore()
+
+ _draw_pixbuf(self.canvas, pixbuf, a, b, x, y, w, h, self.heading)
self.inval()
- if self.tw.saving_svg:
- if self.tw.running_sugar:
- # In Sugar, we embed the images inside the SVG
- tmp_file = os.path.join(get_path(self.tw.activity, 'instance'),
- 'tmpfile.png')
- pixbuf.save(tmp_file, 'png', {'quality': '100'})
- self.tw.svg_string += self.svg.image(
- x, y, w, h, path,
- image_to_base64(tmp_file,
- get_path(self.tw.activity, 'instance')))
- os.remove(tmp_file)
- else:
- # In GNOME, we embed a path
- self.tw.svg_string += self.svg.image(
- x - self.width / 2, y, w, h, path)
+ if self.cr_svg is not None:
+ _draw_pixbuf(self.cr_svg, pixbuf, a, b, x, y, w, h, self.heading)
if self.tw.sharing() and share:
if self.tw.running_sugar:
tmp_path = get_path(self.tw.activity, 'instance')
@@ -590,31 +597,34 @@ class TurtleGraphics:
def draw_text(self, label, x, y, size, w, share=True):
''' Draw text '''
w *= self.tw.coord_scale
- cr = pangocairo.CairoContext(self.canvas)
- pl = cr.create_layout()
- fd = pango.FontDescription('Sans')
- fd.set_size(int(size * self.tw.coord_scale) * pango.SCALE)
- pl.set_font_description(fd)
- if type(label) == str or type(label) == unicode:
- pl.set_text(label.replace('\0', ' '))
- elif type(label) == float or type(label) == int:
- pl.set_text(str(label))
- else:
- pl.set_text(str(label))
- pl.set_width(int(w) * pango.SCALE)
- cr.save()
- cr.translate(x, y)
- cr.rotate(self.heading * DEGTOR)
- self.canvas.set_source_rgb(self.fgrgb[0] / 255.,
- self.fgrgb[1] / 255.,
- self.fgrgb[2] / 255.)
- cr.update_layout(pl)
- cr.show_layout(pl)
- cr.restore()
+
+ def _draw_text(cr, label, x, y, size, w, scale, heading, rgb):
+ cc = pangocairo.CairoContext(cr)
+ pl = cc.create_layout()
+ fd = pango.FontDescription('Sans')
+ fd.set_size(int(size * scale) * pango.SCALE)
+ pl.set_font_description(fd)
+ if type(label) == str or type(label) == unicode:
+ pl.set_text(label.replace('\0', ' '))
+ elif type(label) == float or type(label) == int:
+ pl.set_text(str(label))
+ else:
+ pl.set_text(str(label))
+ pl.set_width(int(w) * pango.SCALE)
+ cc.save()
+ cc.translate(x, y)
+ cc.rotate(heading * DEGTOR)
+ cr.set_source_rgb(rgb[0] / 255., rgb[1] / 255., rgb[2] / 255.)
+ cc.update_layout(pl)
+ cc.show_layout(pl)
+ cc.restore()
+
+ _draw_text(self.canvas, label, x, y, size, w, self.tw.coord_scale,
+ self.heading, self.fgrgb)
self.inval()
- if self.tw.saving_svg: # and self.pendown:
- self.tw.svg_string += self.svg.text(x, # - self.width / 2,
- y + size, size, w, label)
+ if self.cr_svg is not None: # and self.pendown:
+ _draw_text(self.cr_svg, label, x, y, size, w, self.tw.coord_scale,
+ self.heading, self.fgrgb)
if self.tw.sharing() and share:
event = 'W|%s' % (data_to_string([self._get_my_nick(),
[label, round_int(x),
@@ -640,21 +650,19 @@ class TurtleGraphics:
x1, y1 = self.turtle_to_screen_coordinates(x1, y1)
x2, y2 = self.turtle_to_screen_coordinates(x2, y2)
- self.canvas.move_to(x1, y1)
- self.canvas.line_to(x2, y2)
- self.canvas.stroke()
+ def _draw_line(cr, x1, y1, x2, y2):
+ cr.move_to(x1, y1)
+ cr.line_to(x2, y2)
+ cr.stroke()
+ _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))
- if self.tw.saving_svg and self.pendown:
- self.tw.svg_string += self.svg.new_path(x1, y1)
- self.tw.svg_string += self.svg.line_to(x2, y2)
- self.tw.svg_string += '"\n'
- self.tw.svg_string += self.svg.style()
-
def turn_turtle(self):
''' Change the orientation of the turtle '''
self.tw.active_turtle.set_heading(self.heading)
@@ -665,7 +673,8 @@ class TurtleGraphics:
if self.tw.interactive_mode:
self.tw.active_turtle.move(
(int(self.cx + x - self.tw.active_turtle.spr.rect.width / 2.),
- int(self.cy + y - self.tw.active_turtle.spr.rect.height / 2.)))
+ int(self.cy + y - self.tw.active_turtle.spr.rect.height / 2.))
+ )
else:
self.tw.active_turtle.move((int(self.cx + x), int(self.cy + y)))
@@ -713,15 +722,14 @@ class TurtleGraphics:
if x < 0 or x > (w - 1) or y < 0 or y > (h - 1):
return(-1, -1, -1, -1)
# create a new 1x1 cairo surface
- cs = cairo.ImageSurface(cairo.FORMAT_RGB24, 1, 1);
+ cs = cairo.ImageSurface(cairo.FORMAT_RGB24, 1, 1)
cr = cairo.Context(cs)
cr.set_source_surface(self.tw.turtle_canvas, -x, -y)
- cr.rectangle(0,0,1,1)
+ cr.rectangle(0, 0, 1, 1)
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.fill()
- cs.flush() # ensure all writing is done
- # Read the pixel
- pixels = cs.get_data()
+ cs.flush() # ensure all writing is done
+ pixels = cs.get_data() # Read the pixel
return (ord(pixels[2]), ord(pixels[1]), ord(pixels[0]), 0)
else:
return(-1, -1, -1, -1)
@@ -754,14 +762,11 @@ class TurtleGraphics:
def svg_close(self):
''' Close current SVG graphic '''
- if self.tw.svg_string == '':
- return
- self.svg.calc_w_h(False)
- self.tw.svg_string = '%s %s %s %s' % (
- self.svg.header(True),
- self.svg.background('#%02x%02x%02x' % (
- self.bgrgb[0], self.bgrgb[1], self.bgrgb[2])),
- self.tw.svg_string, self.svg.footer())
+ self.cr_svg.show_page()
+
+ def svg_reset(self):
+ ''' Reset svg flags '''
+ self.cr_svg = None
def _get_my_nick(self):
return self.tw.nick
diff --git a/TurtleArt/taconstants.py b/TurtleArt/taconstants.py
index 6bbaf69..7a82a42 100644
--- a/TurtleArt/taconstants.py
+++ b/TurtleArt/taconstants.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-#Copyright (c) 2010-11 Walter Bender
+#Copyright (c) 2010-12 Walter Bender
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
@@ -104,17 +104,6 @@ COLLAPSIBLE = ['sandwichbottom', 'sandwichcollapsed']
#
OLD_DOCK = ['and', 'or', 'plus', 'minus', 'division', 'product', 'remainder']
-#
-# Blocks that can interchange strings and numbers for their arguments
-#
-STRING_OR_NUMBER_ARGS = ['plus2', 'equal2', 'less2', 'greater2', 'box',
- 'template1x1', 'template1x2', 'template2x1', 'list',
- 'template2x2', 'template1x1a', 'templatelist', 'nop',
- 'print', 'stack', 'hat', 'addturtle', 'myfunc',
- 'myfunc1arg', 'myfunc2arg', 'myfunc3arg', 'comment',
- 'sandwichtop', 'sandwichtop_no_arm', 'userdefined',
- 'userdefined2args', 'userdefined3args', 'storein']
-
CONTENT_ARGS = ['show', 'showaligned', 'push', 'storein', 'storeinbox1',
'storeinbox2']
diff --git a/TurtleArt/tagplay.py b/TurtleArt/tagplay.py
index dbce7ed..72379c6 100644
--- a/TurtleArt/tagplay.py
+++ b/TurtleArt/tagplay.py
@@ -67,7 +67,7 @@ def play_movie_from_file(lc, filepath, x, y, w, h):
def stop_media(lc):
""" Called from Clean block and toolbar Stop button """
if lc.gplay == None:
- return
+ return False
if lc.gplay.player is not None:
lc.gplay.player.stop()
@@ -269,6 +269,7 @@ class GstPlayer(gobject.GObject):
self.player.set_state(gst.STATE_NULL)
self.playing = False
logging.debug('stopped player')
+ return False
def get_state(self, timeout=1):
return self.player.get_state(timeout=timeout)
diff --git a/TurtleArt/talogo.py b/TurtleArt/talogo.py
index a2901eb..590797c 100644
--- a/TurtleArt/talogo.py
+++ b/TurtleArt/talogo.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#Copyright (c) 2007-8, Playful Invention Company.
-#Copyright (c) 2008-11, Walter Bender
+#Copyright (c) 2008-12, Walter Bender
#Copyright (c) 2008-10, Raúl Gutiérrez Segalés
#Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -62,10 +62,13 @@ class symbol:
class logoerror(Exception):
def __init__(self, value):
+ print value
self.value = value
def __str__(self):
- return repr(self.value)
+ # return repr(self.value)
+ return str(self.value)
+
class HiddenBlock:
@@ -82,6 +85,7 @@ class HiddenBlock:
# Utility functions
+
def _just_stop():
""" yield False to stop stack """
yield False
@@ -174,7 +178,6 @@ class LogoCode:
self.stacks[k] = None
self.stacks['stack1'] = None
self.stacks['stack2'] = None
- self.tw.saving_svg = False
# Save state in case there is a hidden macro expansion
self.save_blocks = None
@@ -212,6 +215,7 @@ class LogoCode:
x = b.connections[1].values[0]
except IndexError:
self.tw.showlabel('#nostack')
+ self.tw.showblocks()
return None
if type(convert(x, float, False)) == float:
if int(float(x)) == x:
@@ -249,8 +253,6 @@ class LogoCode:
dock = blk.docks[0]
if len(dock) > 4: # There could be a '(', ')', '[' or ']'.
code.append(dock[4])
- if blk.name == 'savesvg':
- self.tw.saving_svg = True
if blk.primitive is not None: # make a tuple (prim, blk)
# special case: expand 'while' and 'until' primitives
try:
@@ -265,8 +267,9 @@ class LogoCode:
except ValueError:
code.append(float(ord(blk.values[0][0])))
elif blk.name == 'string' or \
- blk.name == 'title': # deprecated block
- if type(blk.values[0]) == float or type(blk.values[0]) == int:
+ blk.name == 'title': # deprecated block
+ if type(blk.values[0]) == float or \
+ type(blk.values[0]) == int:
if int(blk.values[0]) == blk.values[0]:
blk.values[0] = int(blk.values[0])
code.append('#s' + str(blk.values[0]))
@@ -342,13 +345,23 @@ class LogoCode:
""" Step through the list. """
if self.tw.running_sugar:
self.tw.activity.stop_turtle_button.set_icon("stopiton")
+ self.tw.activity.stop_turtle_button.set_tooltip(
+ _('Stop turtle'))
elif self.tw.interactive_mode:
self.tw.toolbar_shapes['stopiton'].set_layer(TAB_LAYER)
self.running = True
self.icall(self.evline, blklist)
yield True
if self.tw.running_sugar:
- self.tw.activity.stop_turtle_button.set_icon("stopitoff")
+ # self.tw.activity.stop_turtle_button.set_icon("stopitoff")
+ if self.tw.step_time == 0 and self.tw.selected_blk is None:
+ self.tw.activity.stop_turtle_button.set_icon("hideshowoff")
+ self.tw.activity.stop_turtle_button.set_tooltip(
+ _('Show blocks'))
+ else:
+ self.tw.activity.stop_turtle_button.set_icon("stopitoff")
+ self.tw.activity.stop_turtle_button.set_tooltip(
+ _('Stop turtle'))
elif self.tw.interactive_mode:
self.tw.toolbar_shapes['stopiton'].hide()
yield False
@@ -403,6 +416,7 @@ class LogoCode:
if self.bindex is not None:
self.tw.block_list.list[self.bindex].highlight()
+ self.tw.showblocks()
raise logoerror(str(self.iresult))
self.iline = oldiline
self.ireturn()
@@ -441,6 +455,7 @@ class LogoCode:
self.cfun, self.arglist = token, []
if token.nargs == None:
+ self.tw.showblocks()
raise logoerror("#noinput")
for i in range(token.nargs):
self._no_args_check()
@@ -461,6 +476,7 @@ class LogoCode:
result = self.cfun.fcn(self, *self.arglist)
self.cfun, self.arglist = oldcfun, oldarglist
if self.arglist is not None and result == None:
+ self.tw.showblocks()
raise logoerror("%s %s %s" % \
(oldcfun.name, _("did not output to"), self.cfun.name))
self.ireturn(result)
@@ -495,7 +511,8 @@ class LogoCode:
self.tw.active_turtle.show()
return False
except logoerror, e:
- self.tw.showlabel('syntaxerror', str(e)[1:-1])
+ self.tw.showblocks()
+ self.tw.showlabel('syntaxerror', str(e))
self.tw.turtles.show_all()
return False
return True
@@ -517,12 +534,14 @@ class LogoCode:
errormsg = ''
else:
errormsg = "%s %s" % (_("I don't know how to"), _(token.name))
+ self.tw.showblocks()
raise logoerror(errormsg)
def _no_args_check(self):
""" Missing argument ? """
if self.iline and self.iline[0] is not self.symnothing:
return
+ self.tw.showblocks()
raise logoerror("#noinput")
#
@@ -542,7 +561,7 @@ class LogoCode:
def prim_clear(self):
""" Clear screen """
- self.tw.clear_plugins()
+ self.tw.clear_plugins()
if self.tw.gst_available:
from tagplay import stop_media
# stop_media(self) # TODO: gplay variable
@@ -562,6 +581,7 @@ class LogoCode:
elif type(n) == str:
return int(ord(n[0]))
else:
+ self.tw.showblocks()
raise logoerror("%s %s %s %s" \
% (self.cfun.name, _("doesn't like"), str(n), _("as input")))
@@ -660,8 +680,10 @@ class LogoCode:
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)
+ 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(),
@@ -733,11 +755,11 @@ class LogoCode:
# into trouble if any of these block types (forever, while,
# until. ifelse, stopstack, or stack) is changed in tablock.py
if b.name == 'while':
- while_blk = True
+ while_blk = True
else:
while_blk = False
if b.name == 'until':
- until_blk = True
+ until_blk = True
else:
until_blk = False
@@ -849,7 +871,8 @@ class LogoCode:
c = whileflow.connections[0]
whileflow.connections[0] = None
code = self._blocks_to_code(whileflow)
- self.stacks['stack3' + str(action_flow_name)] = self._readline(code)
+ self.stacks['stack3' + str(action_flow_name)] = \
+ self._readline(code)
whileflow.connections[0] = c
# Save the connections so we can restore them later
diff --git a/TurtleArt/tapalette.py b/TurtleArt/tapalette.py
index da80386..ad96103 100644
--- a/TurtleArt/tapalette.py
+++ b/TurtleArt/tapalette.py
@@ -36,6 +36,7 @@ content_blocks = ['number', 'string', 'description', 'audio', 'video',
hidden_proto_blocks = [] # proto blocks that are (at least initially) hidden
value_blocks = [] # blocks whose labels are updated get added here
special_block_colors = {}
+string_or_number_args = []
block_styles = {'basic-style': [],
'blank-style': [],
'basic-style-head': [],
@@ -86,6 +87,8 @@ from sugar.graphics import style
from taconstants import EXPANDABLE_STYLE
from tautils import debug_output
+from util.helpbutton import add_section, add_paragraph
+
from gettext import gettext as _
help_strings = {
@@ -101,26 +104,26 @@ class Palette():
self._name = name
self._special_name = _(name)
self._colors = colors
- self._help = None
self._max_text_width = int(gtk.gdk.screen_width() / 3) - 20
# Prepare a vbox for the help palette
- if not (self._name in help_palettes):
+ if not self._name in help_palettes:
self._help_box = gtk.VBox()
self._help_box.set_homogeneous(False)
help_palettes[self._name] = self._help_box
+ help_windows[self._name] = gtk.ScrolledWindow()
+ help_windows[self._name].set_size_request(
+ int(gtk.gdk.screen_width() / 3),
+ gtk.gdk.screen_height() - style.GRID_CELL_SIZE * 3)
+ help_windows[self._name].set_policy(
+ gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ help_windows[self._name].add_with_viewport(
+ help_palettes[self._name])
+ help_palettes[self._name].show()
+ self._help = None
else:
self._help_box = help_palettes[self._name]
-
- help_windows[self._name] = gtk.ScrolledWindow()
- help_windows[self._name].set_size_request(
- int(gtk.gdk.screen_width() / 3),
- gtk.gdk.screen_height() - style.GRID_CELL_SIZE * 3)
- help_windows[self._name].set_policy(
- gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- help_windows[self._name].add_with_viewport(
- help_palettes[self._name])
- help_palettes[self._name].show()
+ self._help = 'deja vu'
def add_palette(self, position=None):
if self._name is None:
@@ -141,7 +144,6 @@ class Palette():
palette_blocks.insert(i, [])
block_colors.insert(i, self._colors)
else:
- # debug_output('Palette %s already defined' % (self._name))
return
# Special name entry is needed for help hover mechanism
@@ -151,48 +153,11 @@ class Palette():
else:
help_strings[self._name] = ''
- def add_section(self, section_text, icon=None):
- ''' Add a section to the help palette. From helpbutton.py by
- Gonzalo Odiard '''
- hbox = gtk.HBox()
- label = gtk.Label()
- label.set_use_markup(True)
- label.set_markup('<b>%s</b>' % section_text)
- label.set_line_wrap(True)
- label.set_size_request(self._max_text_width, -1)
- hbox.add(label)
- if icon is not None:
- _icon = Icon(icon_name=icon)
- hbox.add(_icon)
- label.set_size_request(self._max_text_width - 20, -1)
- else:
- label.set_size_request(self._max_text_width, -1)
-
- hbox.show_all()
- self._help_box.pack_start(hbox, False, False, padding=5)
-
- def add_paragraph(self, text, icon=None):
- ''' Add an entry to the help palette. From helpbutton.py by
- Gonzalo Odiard '''
- hbox = gtk.HBox()
- label = gtk.Label(text)
- label.set_justify(gtk.JUSTIFY_LEFT)
- label.set_line_wrap(True)
- hbox.add(label)
- if icon is not None:
- _icon = Icon(icon_name=icon)
- hbox.add(_icon)
- label.set_size_request(self._max_text_width - 20, -1)
- else:
- label.set_size_request(self._max_text_width, -1)
-
- hbox.show_all()
- self._help_box.pack_start(hbox, False, False, padding=5)
-
def set_help(self, help):
- self._help = help
- if hasattr(self, '_help_box'):
- self.add_section(self._help, icon=self._name + 'off')
+ if self._help is None:
+ self._help = help
+ if hasattr(self, '_help_box'):
+ add_section(self._help_box, self._help, icon=self._name + 'off')
def set_special_name(self, name):
self._special_name = name
@@ -200,7 +165,8 @@ class Palette():
def add_block(self, block_name, style='basic-block', label=None,
special_name=None, default=None, prim_name=None,
help_string=None, value_block=False, content_block=False,
- logo_command=None, hidden=False, colors=None):
+ logo_command=None, hidden=False, colors=None,
+ string_or_number=False):
""" Add a new block to the palette """
block = Block(block_name)
block.set_style(style)
@@ -220,15 +186,23 @@ class Palette():
if help_string is not None:
block.set_help(help_string)
if not hidden:
+ first_arg = None
if special_name is None:
if type(label) == list:
- self.add_paragraph('%s: %s' % (label[0], help_string))
+ first_arg = label[0]
else:
- self.add_paragraph('%s: %s' % (label, help_string))
+ first_arg = label
+ else:
+ first_arg = special_name
+ if first_arg is None or first_arg == '' or first_arg == ' ':
+ add_paragraph(self._help_box, '%s' % (help_string))
else:
- self.add_paragraph('%s: %s' % (special_name, help_string))
+ add_paragraph(self._help_box, '%s: %s' % (first_arg,
+ help_string))
if colors is not None:
block.set_colors(colors)
+ if string_or_number:
+ block.set_string_or_number()
block.set_value_block(value_block)
block.set_content_block(content_block)
block.set_palette(self._name)
@@ -236,6 +210,7 @@ class Palette():
block.set_hidden()
block.add_block()
+
def make_palette(palette_name, colors=None, help_string=None, position=None):
""" Palette helper function """
if colors is None:
@@ -279,6 +254,7 @@ class Block():
self._content_block = False
self._colors = None
self._hidden = False
+ self._string_or_number = False
def add_block(self, position=None):
if self._name is None:
@@ -301,13 +277,17 @@ class Block():
if self._palette is not None:
i = palette_names.index(self._palette)
- if position is not None and type(position) is int and \
- position < len(palette_blocks[i]):
- palette_blocks[i].insert(position, self._name)
+ if self._name in palette_blocks[i]:
+ debug_output('%s already in palette %s, skipping...' % (
+ self._name, self._palette))
else:
- palette_blocks[i].append(self._name)
- if position is not None:
- debug_output('Ignoring position (%s)' % (str(position)))
+ if position is not None and type(position) is int and \
+ position < len(palette_blocks[i]):
+ palette_blocks[i].insert(position, self._name)
+ else:
+ palette_blocks[i].append(self._name)
+ if position is not None:
+ debug_output('Ignoring position (%s)' % (str(position)))
if self._help is not None:
help_strings[self._name] = self._help
@@ -338,6 +318,9 @@ class Block():
if self._colors is not None:
special_block_colors[self._name] = self._colors
+ if self._string_or_number:
+ string_or_number_args.append(self._name)
+
if self._hidden:
hidden_proto_blocks.append(self._name)
@@ -347,6 +330,9 @@ class Block():
def set_colors(self, colors=None):
self._colors = colors
+ def set_string_or_number(self, flag=True):
+ self._string_or_number = flag
+
def set_value_block(self, value=True):
self._value_block = value
diff --git a/TurtleArt/tasprite_factory.py b/TurtleArt/tasprite_factory.py
index b750aad..2b0e922 100755
--- a/TurtleArt/tasprite_factory.py
+++ b/TurtleArt/tasprite_factory.py
@@ -595,6 +595,31 @@ class SVG:
svg += self.footer()
return self.header() + svg
+ def status_block(self, graphic=None):
+ ''' Generate a status block '''
+ self.reset_min_max()
+ (x, y) = self._calculate_x_y()
+ self.margins[2] = 0
+ self.margins[3] = 0
+ svg = self.new_path(x, y)
+ svg += self._corner(1, -1)
+ svg += self._rline_to(self._expand_x, 0)
+ xx = self._x
+ svg += self._corner(1, 1)
+ svg += self._rline_to(0, self._expand_y)
+ svg += self._corner(-1, 1)
+ svg += self.line_to(xx, self._y)
+ svg += self._rline_to(-self._expand_x, 0)
+ svg += self._corner(-1, -1)
+ svg += self._rline_to(0, -self._expand_y)
+ self.calc_w_h()
+ svg += self._close_path()
+ svg += self.style()
+ if self._hide is True:
+ svg += self._hide_dot()
+ svg += self.footer()
+ return self.header() + svg
+
#
# Utility methods
#
diff --git a/TurtleArt/taturtle.py b/TurtleArt/taturtle.py
index c13c494..c70f379 100644
--- a/TurtleArt/taturtle.py
+++ b/TurtleArt/taturtle.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-#Copyright (c) 2010,11 Walter Bender
+#Copyright (c) 2010,12 Walter Bender
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
@@ -129,10 +129,10 @@ class Turtle:
self._prep_shapes(key, turtles, turtle_colors)
- # Choose a random angle from which to attach the turtle label
+ # Choose a random angle from which to attach the turtle label.
if turtles.sprite_list is not None:
self.spr = Sprite(turtles.sprite_list, 0, 0, self.shapes[0])
- angle = uniform(0, pi * 4 / 3.0) # 240 degrees
+ angle = uniform(0, pi * 4 / 3.0) # 240 degrees
w = self.shapes[0].get_width()
r = w * 0.67
# Restrict angle the the sides 30-150; 210-330
diff --git a/TurtleArt/tautils.py b/TurtleArt/tautils.py
index 97b396d..40c39e9 100644
--- a/TurtleArt/tautils.py
+++ b/TurtleArt/tautils.py
@@ -1,5 +1,5 @@
#Copyright (c) 2007-8, Playful Invention Company.
-#Copyright (c) 2008-11, Walter Bender
+#Copyright (c) 2008-12, Walter Bender
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
@@ -274,7 +274,10 @@ def save_picture(canvas, file_name):
cr = cairo.Context(img_surface)
cr.set_source_surface(x_surface)
cr.paint()
- img_surface.write_to_png(file_name)
+ if type(file_name) == unicode:
+ img_surface.write_to_png(str(file_name.encode('ascii', 'replace')))
+ else:
+ img_surface.write_to_png(str(file_name))
def get_canvas_data(canvas):
@@ -288,13 +291,6 @@ def get_canvas_data(canvas):
return img_surface.get_data()
-def save_svg(string, file_name):
- ''' Write a string to a file. '''
- file_handle = file(file_name, 'w')
- file_handle.write(string)
- file_handle.close()
-
-
def get_pixbuf_from_journal(dsobject, w, h):
''' Load a pixbuf from a Journal object. '''
try:
@@ -798,7 +794,7 @@ def find_blk_below(blk, name):
if blk == None or len(blk.connections) == 0:
return
group = find_group(blk)
- for gblk in _group:
+ for gblk in group:
if gblk.name == name:
return gblk
return None
diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py
index 20eeb34..b7523e5 100644
--- a/TurtleArt/tawindow.py
+++ b/TurtleArt/tawindow.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#Copyright (c) 2007, Playful Invention Company
-#Copyright (c) 2008-11, Walter Bender
+#Copyright (c) 2008-12, Walter Bender
#Copyright (c) 2009-11 Raúl Gutiérrez Segalés
#Copyright (c) 2011 Collabora Ltd. <http://www.collabora.co.uk/>
@@ -36,6 +36,7 @@ except ImportError:
GST_AVAILABLE = False
import os
+import subprocess
from math import atan2, pi
DEGTOR = 2 * pi / 360
@@ -43,7 +44,7 @@ DEGTOR = 2 * pi / 360
import locale
from taconstants import HORIZONTAL_PALETTE, VERTICAL_PALETTE, BLOCK_SCALE, \
- MEDIA_SHAPES, STATUS_SHAPES, OVERLAY_SHAPES, STRING_OR_NUMBER_ARGS, \
+ MEDIA_SHAPES, STATUS_SHAPES, OVERLAY_SHAPES, \
TOOLBAR_SHAPES, TAB_LAYER, RETURN, OVERLAY_LAYER, CATEGORY_LAYER, \
BLOCKS_WITH_SKIN, ICON_SIZE, PALETTE_SCALE, PALETTE_WIDTH, SKIN_PATHS, \
MACROS, TOP_LAYER, BLOCK_LAYER, OLD_NAMES, DEFAULT_TURTLE, TURTLE_LAYER, \
@@ -53,7 +54,7 @@ from taconstants import HORIZONTAL_PALETTE, VERTICAL_PALETTE, BLOCK_SCALE, \
CONSTANTS, EXPAND_SKIN, PROTO_LAYER
from tapalette import palette_names, palette_blocks, expandable_blocks, \
block_names, content_blocks, default_values, special_names, block_styles, \
- help_strings, hidden_proto_blocks
+ help_strings, hidden_proto_blocks, string_or_number_args
from talogo import LogoCode
from tacanvas import TurtleGraphics
from tablock import Blocks, Block
@@ -61,7 +62,7 @@ from taturtle import Turtles, Turtle
from tautils import magnitude, get_load_name, get_save_name, data_from_file, \
data_to_file, round_int, get_id, get_pixbuf_from_journal, \
movie_media_type, audio_media_type, image_media_type, save_picture, \
- save_svg, calc_image_size, get_path, reset_stack_arm, grow_stack_arm, \
+ calc_image_size, get_path, reset_stack_arm, grow_stack_arm, \
find_sandwich_top, find_sandwich_bottom, restore_stack, collapse_stack, \
collapsed, collapsible, hide_button_hit, show_button_hit, chooser, \
arithmetic_check, xy, find_block_to_run, find_top_block, journal_check, \
@@ -76,6 +77,7 @@ if GST_AVAILABLE:
MOTION_THRESHOLD = 6
SNAP_THRESHOLD = 200
+
class TurtleArtWindow():
""" TurtleArt Window class abstraction """
timeout_tag = [0]
@@ -199,10 +201,9 @@ class TurtleArtWindow():
self.drag_group = None
self.drag_turtle = 'move', 0, 0
self.drag_pos = 0, 0
+ self.dragging_canvas = [False, 0, 0]
self.turtle_movement_to_share = None
self.paste_offset = 20 # Don't paste on top of where you copied.
- self.saving_svg = False
- self.svg_string = ''
self.block_list = Blocks(font_scale_factor=self.scale,
decimal_point=self.decimal_point)
@@ -289,29 +290,25 @@ class TurtleArtWindow():
""" Try importing plugin files from the plugin dir. """
for plugin_dir in self._get_plugins_from_plugins_dir(
self._get_plugin_home()):
- plugin_class = plugin_dir.capitalize()
- f = "def f(self): from plugins.%s.%s import %s; return %s(self)" \
- % (plugin_dir, plugin_dir, plugin_class, plugin_class)
- plugins = {}
- try:
- exec f in globals(), plugins
- self._plugins.append(plugins.values()[0](self))
- debug_output('successfully importing %s' % (plugin_class),
- self.running_sugar)
- except ImportError, e:
- debug_output('failed to import %s: %s' % (plugin_class, str(e)),
- self.running_sugar)
- '''
+ self.init_plugin(plugin_dir)
+
+ def init_plugin(self, plugin_dir):
+ """ Initialize plugin in plugin_dir """
+ plugin_class = plugin_dir.capitalize()
+ f = "def f(self): from plugins.%s.%s import %s; return %s(self)" \
+ % (plugin_dir, plugin_dir, plugin_class, plugin_class)
+ plugins = {}
+ try:
exec f in globals(), plugins
self._plugins.append(plugins.values()[0](self))
- debug_output('successfully importing %s' % (plugin_class))
- '''
-
- # Add the icon dir for each plugin to the icon_theme search path
- for plugin_dir in self._get_plugins_from_plugins_dir(
- self._get_plugin_home()):
+ debug_output('Successfully importing %s' % (plugin_class),
+ self.running_sugar)
+ # Add the icon dir to the icon_theme search path
self._add_plugin_icon_dir(os.path.join(self._get_plugin_home(),
plugin_dir))
+ except ImportError, e:
+ debug_output('Failed to import %s: %s' % (plugin_class, str(e)),
+ self.running_sugar)
def _add_plugin_icon_dir(self, dirname):
''' If there is an icon subdir, add it to the search path. '''
@@ -347,7 +344,7 @@ class TurtleArtWindow():
plugin.stop()
def clear_plugins(self):
- """ Clear is called from the clean block and erase button. """
+ """ Clear is called from the clean block and erase button. """
for plugin in self._plugins:
if hasattr(plugin, 'clear'):
plugin.clear()
@@ -380,10 +377,11 @@ class TurtleArtWindow():
self.window.connect("motion-notify-event", self._move_cb)
self.window.connect("key-press-event", self._keypress_cb)
- def _setup_misc(self):
- """ Misc. sprites for status, overlays, etc. """
- # media blocks get positioned into other blocks
+ def load_media_shapes(self):
+ """ Media shapes get positioned onto blocks """
for name in MEDIA_SHAPES:
+ if name in self.media_shapes:
+ continue
if name[0:7] == 'journal' and not self.running_sugar:
filename = 'file' + name[7:]
else:
@@ -396,9 +394,17 @@ class TurtleArtWindow():
os.path.join(self.path, path, filename + '.svg')))
break
+ def _setup_misc(self):
+ """ Misc. sprites for status, overlays, etc. """
+ self.load_media_shapes()
for i, name in enumerate(STATUS_SHAPES):
- self.status_shapes[name] = svg_str_to_pixbuf(svg_from_file(
- os.path.join(self.path, 'images', name + '.svg')))
+ # Temporary hack to use wider shapes
+ if name in ['print', 'help', 'status'] and self.width > 1024:
+ self.status_shapes[name] = svg_str_to_pixbuf(svg_from_file(
+ os.path.join(self.path, 'images', name + '1200.svg')))
+ else:
+ self.status_shapes[name] = svg_str_to_pixbuf(svg_from_file(
+ os.path.join(self.path, 'images', name + '.svg')))
self.status_spr = Sprite(self.sprite_list, 0, self.height - 200,
self.status_shapes['status'])
self.status_spr.hide()
@@ -414,7 +420,8 @@ class TurtleArtWindow():
self.overlay_shapes[name].type = 'overlay'
if not self.running_sugar:
- offset = self.width - 55 * len(TOOLBAR_SHAPES)
+ # offset = 2 * self.width - 55 * len(TOOLBAR_SHAPES)
+ offset = 55 * (2 + len(palette_blocks))
for i, name in enumerate(TOOLBAR_SHAPES):
self.toolbar_shapes[name] = Sprite(
self.sprite_list, i * 55 + offset, 0,
@@ -459,6 +466,10 @@ class TurtleArtWindow():
# Create the cairo context
cr = self.window.window.cairo_create()
+ # TODO: set global scale
+ # find_sprite needs rescaled coordinates
+ # sw needs new bounds set
+ # cr.scale(self.activity.global_x_scale, self.activity.global_y_scale)
if event is None:
cr.rectangle(self.rect.x, self.rect.y,
@@ -484,7 +495,7 @@ class TurtleArtWindow():
self.lc.prim_clear()
self.display_coordinates()
- def run_button(self, time):
+ def run_button(self, time, running_from_button_push=False):
""" Run turtle! """
if self.running_sugar:
self.activity.recenter()
@@ -495,6 +506,10 @@ class TurtleArtWindow():
self.step_time = time
debug_output("running stack starting from %s" % (blk.name),
self.running_sugar)
+ if running_from_button_push:
+ self.selected_blk = None
+ else:
+ self.selected_blk = blk
self._run_stack(blk)
return
@@ -504,6 +519,10 @@ class TurtleArtWindow():
self.step_time = time
debug_output("running stack starting from %s" % (blk.name),
self.running_sugar)
+ if running_from_button_push:
+ self.selected_blk = None
+ else:
+ self.selected_blk = blk
self._run_stack(blk)
return
@@ -588,6 +607,8 @@ class TurtleArtWindow():
if not self.hide:
for blk in self.just_blocks():
blk.spr.hide()
+ for spr in self.triangle_sprs:
+ spr.hide()
self.hide_palette()
self.hide = True
else:
@@ -629,6 +650,7 @@ class TurtleArtWindow():
self.show_toolbar_palette(n)
self.palette_button[self.orientation].set_layer(TAB_LAYER)
self.palette_button[2].set_layer(TAB_LAYER)
+ self._display_palette_shift_button(n)
if self.activity is None or not self.activity.has_toolbarbox:
self.toolbar_spr.set_layer(CATEGORY_LAYER)
self.palette = True
@@ -638,6 +660,8 @@ class TurtleArtWindow():
self._hide_toolbar_palette()
self.palette_button[self.orientation].hide()
self.palette_button[2].hide()
+ self.palette_button[3].hide()
+ self.palette_button[4].hide()
if self.activity is None or not self.activity.has_toolbarbox:
self.toolbar_spr.hide()
self.palette = False
@@ -715,6 +739,25 @@ class TurtleArtWindow():
if blk.name in BLOCKS_WITH_SKIN:
self._resize_skin(blk)
+ def _shift_toolbar_palette(self, n):
+ ''' Shift blocks on specified palette '''
+ x, y = self.palette_sprs[n][self.orientation].get_xy()
+ w, h = self.palette_sprs[n][self.orientation].get_dimensions()
+ bx, by = self.palettes[n][0].spr.get_xy()
+ if self.orientation == 0:
+ dx = w - self.width
+ dy = 0
+ if bx - x > 0:
+ dx *= -1
+ else:
+ dx = 0
+ dy = h - self.height + ICON_SIZE
+ if by - y > 0:
+ dy *= -1
+ for blk in self.palettes[n]:
+ if blk.get_visibility():
+ blk.spr.move_relative((dx, dy))
+
def show_toolbar_palette(self, n, init_only=False, regenerate=False,
show=True):
""" Show the toolbar palettes, creating them on init_only """
@@ -746,7 +789,8 @@ class TurtleArtWindow():
# Make sure all of the selectors are visible. (We don't need to do
# this for 0.86+ toolbars since the selectors are toolbar buttons.)
- if show and (self.activity is None or not self.activity.has_toolbarbox):
+ if show and \
+ (self.activity is None or not self.activity.has_toolbarbox):
self.selected_selector = self.selectors[n]
self.selectors[n].set_shape(self.selector_shapes[n][1])
for i in range(len(palette_blocks)):
@@ -754,7 +798,9 @@ class TurtleArtWindow():
# Show the palette with the current orientation.
if self.palette_sprs[n][self.orientation] is not None:
- self.palette_sprs[n][self.orientation].set_layer(CATEGORY_LAYER)
+ self.palette_sprs[n][self.orientation].set_layer(
+ CATEGORY_LAYER)
+ self._display_palette_shift_button(n)
# Create 'proto' blocks for each palette entry
self._create_proto_blocks(n)
@@ -784,6 +830,20 @@ class TurtleArtWindow():
self.selected_palette = save_selected
self.previous_palette = save_previous
+ def _display_palette_shift_button(self, n):
+ ''' Palettes too wide (or tall) for the screen get a shift button '''
+ if self.palette_sprs[n][self.orientation].type == \
+ 'category-shift-horizontal':
+ self.palette_button[3].set_layer(CATEGORY_LAYER)
+ self.palette_button[4].hide()
+ elif self.palette_sprs[n][self.orientation].type == \
+ 'category-shift-vertical':
+ self.palette_button[3].hide()
+ self.palette_button[4].set_layer(CATEGORY_LAYER)
+ else:
+ self.palette_button[3].hide()
+ self.palette_button[4].hide()
+
def _create_the_selectors(self):
''' Create the palette selector buttons: only when running
old-style Sugar toolbars or from GNOME '''
@@ -824,7 +884,7 @@ class TurtleArtWindow():
# Create the toolbar background for the selectors
self.toolbar_offset = ICON_SIZE
self.toolbar_spr = Sprite(self.sprite_list, 0, 0,
- svg_str_to_pixbuf(svg.toolbar(self.width, ICON_SIZE)))
+ svg_str_to_pixbuf(svg.toolbar(2 * self.width, ICON_SIZE)))
self.toolbar_spr.type = 'toolbar'
self.toolbar_spr.set_layer(CATEGORY_LAYER)
@@ -860,11 +920,32 @@ class TurtleArtWindow():
self.palette_button[2].type = 'palette'
self.palette_button[2].set_layer(TAB_LAYER)
+ # Create the palette shift buttons
+ dims = self.palette_button[0].get_dimensions()
+ self.palette_button.append(Sprite(self.sprite_list, 0,
+ self.toolbar_offset + dims[1], svg_str_to_pixbuf(svg_from_file(
+ "%s/images/palettehshift.svg" % (self.path)))))
+ self.palette_button.append(Sprite(self.sprite_list, dims[0],
+ self.toolbar_offset, svg_str_to_pixbuf(svg_from_file(
+ "%s/images/palettevshift.svg" % (self.path)))))
+ self.palette_button[3].name = _('shift')
+ self.palette_button[4].name = _('shift')
+ self.palette_button[3].type = 'palette'
+ self.palette_button[4].type = 'palette'
+ self.palette_button[3].hide()
+ self.palette_button[4].hide()
+
def _create_proto_blocks(self, n):
''' Create the protoblocks that will populate a palette. '''
# Reload the palette, but reuse the existing blocks
# If a block doesn't exist, add it
+ if not n < len(self.palettes):
+ debug_output(
+ '_create_proto_blocks: palette index %d is out of range' % (n),
+ self.running_sugar)
+ return
+
for blk in self.palettes[n]:
blk.spr.hide()
old_blocks = self.palettes[n][:]
@@ -900,7 +981,7 @@ class TurtleArtWindow():
elif name in PYTHON_SKIN:
self._proto_skin('pythonsmall', n, -1)
return
-
+
def _hide_toolbar_palette(self):
""" Hide the toolbar palettes """
self._hide_previous_palette()
@@ -919,6 +1000,11 @@ class TurtleArtWindow():
palette = self.previous_palette
# Hide previously selected palette
if palette is not None:
+ if not palette < len(self.palettes):
+ debug_output(
+ '_hide_previous_palette: index %d is out of range' % \
+ (palette), self.running_sugar)
+ return
for proto in self.palettes[palette]:
proto.spr.hide()
if self.palette_sprs[palette][self.orientation] is not None:
@@ -1031,11 +1117,14 @@ class TurtleArtWindow():
self.palette_button[2].move((PALETTE_WIDTH - 20,
self.toolbar_offset))
if show:
- self.palette_button[2].save_xy = self.palette_button[2].get_xy()
+ self.palette_button[2].save_xy = \
+ self.palette_button[2].get_xy()
if self.running_sugar and not self.hw in [XO1]:
self.palette_button[2].move_relative(
(self.activity.hadj_value, self.activity.vadj_value))
- self.palette_sprs[n][self.orientation].set_layer(CATEGORY_LAYER)
+ self.palette_sprs[n][self.orientation].set_layer(
+ CATEGORY_LAYER)
+ self._display_palette_shift_button(n)
def _make_palette_spr(self, n, x, y, w, h, regenerate=False):
''' Make the background for the palette. '''
@@ -1051,7 +1140,14 @@ class TurtleArtWindow():
if self.running_sugar and not self.hw in [XO1]:
self.palette_sprs[n][self.orientation].move_relative(
(self.activity.hadj_value, self.activity.vadj_value))
- self.palette_sprs[n][self.orientation].type = 'category'
+ if self.orientation == 0 and w > self.width:
+ self.palette_sprs[n][self.orientation].type = \
+ 'category-shift-horizontal'
+ elif self.orientation == 1 and h > self.height - ICON_SIZE:
+ self.palette_sprs[n][self.orientation].type = \
+ 'category-shift-vertical'
+ else:
+ self.palette_sprs[n][self.orientation].type = 'category'
if n == palette_names.index('trash'):
svg = SVG()
self.palette_sprs[n][self.orientation].set_shape(
@@ -1075,7 +1171,8 @@ class TurtleArtWindow():
# Unselect things that may have been selected earlier
if self.selected_blk is not None:
- if self.selected_blk.name == 'number' and spr in self.triangle_sprs:
+ if self.selected_blk.name == 'number' and \
+ spr in self.triangle_sprs:
# increment or decrement a number block
nf = float(self.selected_blk.spr.labels[0].replace(CURSOR, ''))
ni = int(nf)
@@ -1087,7 +1184,7 @@ class TurtleArtWindow():
n += 1
else:
n -= 1
- self.selected_blk.spr.set_label(str(n) + CURSOR)
+ self.selected_blk.spr.set_label(str(n) + CURSOR)
return True
self._unselect_block()
self.selected_turtle = None
@@ -1098,8 +1195,12 @@ class TurtleArtWindow():
self.dx = 0
self.dy = 0
+ self.dragging_canvas[1] = x
+ self.dragging_canvas[2] = y
if spr is None:
+ self.dragging_canvas[0] = True
return True
+ self.dragging_canvas[0] = False
self.selected_spr = spr
# From the sprite at x, y, look for a corresponding block
@@ -1174,7 +1275,8 @@ class TurtleArtWindow():
if hasattr(spr, 'type'):
if spr.type == 'selector':
self._select_category(spr)
- elif spr.type == 'category':
+ elif spr.type in ['category', 'category-shift-horizontal',
+ 'category-shift-vertical']:
if hide_button_hit(spr, x, y):
self.hideshow_palette(False)
elif spr.type == 'palette':
@@ -1198,6 +1300,8 @@ class TurtleArtWindow():
self.activity.palette_buttons[i].set_icon(
palette_names[i] + 'on')
self.show_palette(i)
+ elif spr.name == _('shift'):
+ self._shift_toolbar_palette(self.selected_palette)
else:
self.orientation = 1 - self.orientation
self.palette_button[self.orientation].set_layer(TAB_LAYER)
@@ -1229,6 +1333,7 @@ class TurtleArtWindow():
return
if spr.name == 'run-fastoff':
self.lc.trace = 0
+ self.hideblocks()
self.run_button(0)
elif spr.name == 'run-slowoff':
self.lc.trace = 1
@@ -1430,7 +1535,6 @@ class TurtleArtWindow():
newblk.connections[i + 1] = argblk
self.drag_group = find_group(newblk)
self.block_operation = 'new'
- debug_output(newblk.name, True)
if len(newblk.spr.labels) > 0 and newblk.spr.labels[0] is not None \
and newblk.name not in ['', 'number', 'string']:
if len(self.used_block_list) > 0:
@@ -1600,6 +1704,15 @@ class TurtleArtWindow():
def _mouse_move(self, x, y):
""" Process mouse movements """
+
+ if self.running_sugar and self.dragging_canvas[0]:
+ dx = self.dragging_canvas[1] - x
+ dy = self.dragging_canvas[2] - y
+ self.dragging_canvas[1] = x
+ self.dragging_canvas[2] = y
+ self.activity.adjust_sw(dx, dy)
+ return True
+
self.block_operation = 'move'
# First, check to see if we are dragging or rotating a turtle.
@@ -1768,6 +1881,13 @@ class TurtleArtWindow():
return True
def button_release(self, x, y):
+ if self.running_sugar and self.dragging_canvas[0]:
+ self.dragging_canvas[0] = False
+ self.dragging_canvas[1] = x
+ self.dragging_canvas[2] = y
+ self.activity.adjust_palette()
+ return True
+
# We may have been moving the turtle
if self.selected_turtle is not None:
(tx, ty) = self.selected_turtle.get_xy()
@@ -2112,6 +2232,10 @@ class TurtleArtWindow():
if blk is None:
return
self.lc.find_value_blocks() # Are there blocks to update?
+ # Is there a savesvg block?
+ if len(self.block_list.get_similar_blocks('block', 'savesvg')) > 0:
+ if self.canvas.cr_svg is None:
+ self.canvas.setup_svg_surface()
self._start_plugins() # Let the plugins know we are running.
top = find_top_block(blk)
self.lc.run_blocks(top, self.just_blocks(), True)
@@ -2184,7 +2308,8 @@ class TurtleArtWindow():
if best_destination_dockn == 2 and \
(selected_block.name in block_styles['boolean-style'] or \
selected_block.name in block_styles['compare-style'] or \
- selected_block.name in block_styles['compare-porch-style']):
+ selected_block.name in block_styles['compare-porch-style']
+ ):
dy = selected_block.ey - best_destination.ey
if selected_block.name in block_styles['boolean-style']:
# Even without expanding, boolean blocks are
@@ -2607,7 +2732,6 @@ class TurtleArtWindow():
else:
n = 0
self.selected_blk.spr.set_label(str(n))
- debug_output(str(n), True)
try:
self.selected_blk.values[0] = \
float(str(n).replace(self.decimal_point, '.'))
@@ -3072,7 +3196,10 @@ class TurtleArtWindow():
label = ''
self.status_spr.set_shape(self.status_shapes[shp])
self.status_spr.set_label_attributes(12.0, rescale=False)
- self.status_spr.set_label(str(label))
+ if shp == 'status':
+ self.status_spr.set_label('"%s"' % (str(label)))
+ else:
+ self.status_spr.set_label(str(label))
self.status_spr.set_layer(STATUS_LAYER)
if shp == 'info':
self.status_spr.move((PALETTE_WIDTH, self.height - 400))
@@ -3136,10 +3263,9 @@ class TurtleArtWindow():
file_path = os.path.join(datapath, filename)
if svg:
- if self.svg_string == '':
+ if self.canvas.cr_svg is None:
return
- save_svg(self.svg_string, file_path)
- self.svg_string = ''
+ self.canvas.svg_reset()
else:
save_picture(self.canvas, file_path)
@@ -3156,14 +3282,22 @@ class TurtleArtWindow():
dsobject.metadata['icon-color'] = profile.get_color().to_string()
if svg:
dsobject.metadata['mime_type'] = 'image/svg+xml'
+ dsobject.set_file_path(os.path.join(datapath, 'output.svg'))
else:
dsobject.metadata['mime_type'] = 'image/png'
- dsobject.set_file_path(file_path)
+ dsobject.set_file_path(file_path)
datastore.write(dsobject)
dsobject.destroy()
self.saved_pictures.append((dsobject.object_id, svg))
- os.remove(file_path)
+ if svg:
+ os.remove(os.path.join(datapath, 'output.svg'))
+ else:
+ os.remove(file_path)
else:
+ if svg:
+ output = subprocess.check_output(
+ ['mv', os.path.join(datapath, 'output.svg'),
+ os.path.join(datapath, filename)])
self.saved_pictures.append((file_path, svg))
def just_blocks(self):
@@ -3275,7 +3409,7 @@ def dock_dx_dy(block1, dock1n, block2, dock2n):
block2.connections[dock2n] is not None:
return (100, 100)
if _d1type != _d2type:
- if block1.name in STRING_OR_NUMBER_ARGS:
+ if block1.name in string_or_number_args:
if _d2type == 'number' or _d2type == 'string':
pass
elif block1.name in CONTENT_ARGS:
diff --git a/TurtleConfusionActivity.py b/TurtleConfusionActivity.py
index 9c2d9d9..2f28b84 100644
--- a/TurtleConfusionActivity.py
+++ b/TurtleConfusionActivity.py
@@ -271,8 +271,10 @@ class TurtleConfusionActivity(activity.Activity):
if not self.has_toolbarbox:
self.palette_buttons[i].set_icon(palette_names[i] + 'on')
+ '''
else:
self._help_button.set_current_palette(palette_names[i])
+ '''
self.tw.show_palette(i)
self.do_showpalette()
@@ -477,8 +479,10 @@ class TurtleConfusionActivity(activity.Activity):
self.read_file(os.path.join(
activity.get_bundle_path(), 'challenges',
'help-' + str(self._level + 1) + '.ta'), run_it=False)
+ '''
else:
self.hover_help_label.set_label(_("no help available"))
+ '''
def get_document_path(self, async_cb, async_err_cb):
''' View TA code as part of view source. '''
@@ -565,8 +569,9 @@ class TurtleConfusionActivity(activity.Activity):
'ta-open', _('Load example'), self.do_samples_cb,
self._toolbox.toolbar)
- self._help_button = HelpButton()
- self._toolbox.toolbar.insert(self._help_button, -1)
+ self._help_button = self._add_button(
+ 'help-toolbar', _('Help'), self._do_help_cb,
+ self._toolbox.toolbar)
stop_button = StopButton(self)
stop_button.props.accelerator = '<Ctrl>Q'
@@ -664,10 +669,6 @@ class TurtleConfusionActivity(activity.Activity):
self.save_as_image = self._add_button(
'image-saveoff', _('Save as image'), self.do_save_as_image_cb,
toolbar)
- '''
- self.save_as_html = self._add_button(
- 'htmloff', _('Save as HTML'), self.do_save_as_html_cb, toolbar)
- '''
self.save_as_logo = self._add_button(
'logo-saveoff', _('Save as Logo'), self.do_save_as_logo_cb,
toolbar)
@@ -678,11 +679,6 @@ class TurtleConfusionActivity(activity.Activity):
self.load_ta_project = self._add_button(
'load-from-journal', _('Import project from the Journal'),
self.do_load_ta_project_cb, toolbar)
- '''
- self.load_python = self._add_button(
- 'pippy-openoff', _('Load Python block'), self.do_load_python_cb,
- toolbar)
- '''
if not self.has_toolbarbox:
self.samples_button = self._add_button(
'ta-open', _('Load example'), self.do_samples_cb, toolbar)
@@ -710,8 +706,6 @@ class TurtleConfusionActivity(activity.Activity):
'run-fastoff', _('Run'), self.do_run_cb, toolbar, _('<Ctrl>r'))
self.step_button = self._add_button(
'run-slowoff', _('Step'), self.do_step_cb, toolbar, _('<Ctrl>w'))
- self.debug_button = self._add_button(
- 'debugoff', _('Debug'), self.do_debug_cb, toolbar, _('<Ctrl>d'))
self.stop_turtle_button = self._add_button(
'stopitoff', _('Stop turtle'), self.do_stop_cb, toolbar,
_('<Ctrl>s'))
diff --git a/activity/activity.info b/activity/activity.info
index 7963c26..6aed98a 100644
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -1,6 +1,6 @@
[Activity]
name = Turtle Confusion
-activity_version = 9
+activity_version = 10
license = MIT
bundle_id = org.laptop.TurtleConfusionActivity
exec = sugar-activity TurtleConfusionActivity.TurtleConfusionActivity
diff --git a/images/help1200.svg b/images/help1200.svg
new file mode 100644
index 0000000..a284973
--- /dev/null
+++ b/images/help1200.svg
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.0"
+ width="1167"
+ height="38"
+ id="svg2">
+ <metadata
+ id="metadata17">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs27" />
+ <path
+ d="M 15,37.5 C 11.5,37.5 8,35 5.5,32.5 3,30 0.5,26.5 0.5,23 l 0,-8 c 0,-3.25 2.5,-8.5 5,-10.5 2.5,-2 6,-4 9.5,-4 l 1136.5,0 c 2.5,0 7,1 10.5,4 3.5,2.75 4.5,7.5 4.5,10.5 l 0,8 c 0,3.5 -2,7 -4.5,9.5 -2.5,2.5 -6.5,5 -10.5,5 z"
+ id="path4"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#e0e0e0;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <g
+ transform="translate(1053.75,65.625)"
+ id="g6">
+ <path
+ d="m 79.5,438.5 c 0,4.5 -3.75,8 -8.5,8 -4.5,0 -8.25,-3.5 -8.25,-8 0,-4.5 3.75,-8.25 8.25,-8.25 4.75,0 8.5,3.75 8.5,8.25 l 0,0 z"
+ transform="translate(24,-485)"
+ id="path8"
+ style="fill:#ff4040;fill-opacity:1;fill-rule:nonzero;stroke:#ff4040;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <text
+ id="text10"
+ style="font-size:12px;font-weight:bold;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans">
+ <tspan
+ x="91"
+ y="-42"
+ id="tspan12"
+ style="font-size:12px">X</tspan>
+ </text>
+ </g>
+</svg>
diff --git a/images/palettehshift.svg b/images/palettehshift.svg
new file mode 100644
index 0000000..38158aa
--- /dev/null
+++ b/images/palettehshift.svg
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="16"
+ height="16"
+ id="svg2">
+ <metadata
+ id="metadata8">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs9">
+ <linearGradient
+ x1="0"
+ y1="17.200001"
+ x2="37"
+ y2="17.200001"
+ id="linearGradient5678"
+ xlink:href="#linearGradient1234"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient1234">
+ <stop
+ id="stop3087"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3089"
+ style="stop-color:#a0ff00;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ </defs>
+ <path
+ d="m 18.983051,7.5932202 a 10.915255,10.169492 0 1 1 -21.8305089,0 10.915255,10.169492 0 1 1 21.8305089,0 z"
+ transform="matrix(0.68421284,0,0,0.73438846,2.4799099,2.4236267)"
+ id="path2819"
+ style="fill:#ffd000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <g
+ transform="matrix(0,-1.3333333,1.3333333,0,-2.6666664,18.666666)"
+ id="g3924">
+ <path
+ d="m 8,4 0,8"
+ id="path3106"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <g
+ transform="translate(0.0303029,-0.060606)"
+ id="g3896">
+ <path
+ d="M 7.939394,4.060606 6,6"
+ id="path3108"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ d="M 8,4.060606 9.9393942,6"
+ id="path3108-6"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ </g>
+ <g
+ transform="matrix(1,0,0,-1,0.0303029,16.060606)"
+ id="g3896-4">
+ <path
+ d="M 7.939394,4.060606 6,6"
+ id="path3108-0"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ d="M 8,4.060606 9.9393942,6"
+ id="path3108-6-8"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ </g>
+ </g>
+</svg>
diff --git a/images/palettevshift.svg b/images/palettevshift.svg
new file mode 100644
index 0000000..504272f
--- /dev/null
+++ b/images/palettevshift.svg
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ width="16"
+ height="16"
+ id="svg2">
+ <metadata
+ id="metadata8">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs9">
+ <linearGradient
+ x1="0"
+ y1="17.200001"
+ x2="37"
+ y2="17.200001"
+ id="linearGradient5678"
+ xlink:href="#linearGradient1234"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient1234">
+ <stop
+ id="stop3087"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3089"
+ style="stop-color:#a0ff00;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ </defs>
+ <path
+ d="m 18.983051,7.5932202 a 10.915255,10.169492 0 1 1 -21.8305089,0 10.915255,10.169492 0 1 1 21.8305089,0 z"
+ transform="matrix(0.68421284,0,0,0.73438846,2.4799099,2.4236267)"
+ id="path2819"
+ style="fill:#ffd000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <g
+ transform="matrix(1.3333333,0,0,1.3333333,-2.6666664,-2.6666664)"
+ id="g3924">
+ <path
+ d="m 8,4 0,8"
+ id="path3106"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <g
+ transform="translate(0.0303029,-0.060606)"
+ id="g3896">
+ <path
+ d="M 7.939394,4.060606 6,6"
+ id="path3108"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ d="M 8,4.060606 9.9393942,6"
+ id="path3108-6"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ </g>
+ <g
+ transform="matrix(1,0,0,-1,0.0303029,16.060606)"
+ id="g3896-4">
+ <path
+ d="M 7.939394,4.060606 6,6"
+ id="path3108-0"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ d="M 8,4.060606 9.9393942,6"
+ id="path3108-6-8"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ </g>
+ </g>
+</svg>
diff --git a/images/print1200.svg b/images/print1200.svg
new file mode 100644
index 0000000..e94402e
--- /dev/null
+++ b/images/print1200.svg
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.0"
+ width="1167"
+ height="38"
+ id="svg2">
+ <metadata
+ id="metadata17">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs27" />
+ <path
+ d="M 15,37.5 C 11.5,37.5 8,35 5.5,32.5 3,30 0.5,26.5 0.5,23 l 0,-8 c 0,-3.25 2.5,-8.5 5,-10.5 2.5,-2 6,-4 9.5,-4 l 1136.5,0 c 2.5,0 7,1 10.5,4 3.5,2.75 4.5,7.5 4.5,10.5 l 0,8 c 0,3.5 -2,7 -4.5,9.5 -2.5,2.5 -6.5,5 -10.5,5 z"
+ id="path4"
+ style="fill:#80ffff;fill-opacity:1;fill-rule:evenodd;stroke:#00e0e0;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <g
+ transform="translate(1053.75,65.625)"
+ id="g6">
+ <path
+ d="m 79.5,438.5 c 0,4.5 -3.75,8 -8.5,8 -4.5,0 -8.25,-3.5 -8.25,-8 0,-4.5 3.75,-8.25 8.25,-8.25 4.75,0 8.5,3.75 8.5,8.25 l 0,0 z"
+ transform="translate(24,-485)"
+ id="path8"
+ style="fill:#ff4040;fill-opacity:1;fill-rule:nonzero;stroke:#ff4040;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <text
+ id="text10"
+ style="font-size:12px;font-weight:bold;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans">
+ <tspan
+ x="91"
+ y="-42"
+ id="tspan12"
+ style="font-size:12px">X</tspan>
+ </text>
+ </g>
+</svg>
diff --git a/images/status1200.svg b/images/status1200.svg
new file mode 100644
index 0000000..6b64812
--- /dev/null
+++ b/images/status1200.svg
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.0"
+ width="1167"
+ height="38"
+ id="svg2">
+ <metadata
+ id="metadata17">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs27" />
+ <path
+ d="M 15,37.5 C 11.5,37.5 8,35 5.5,32.5 3,30 0.5,26.5 0.5,23 l 0,-8 c 0,-3.25 2.5,-8.5 5,-10.5 2.5,-2 6,-4 9.5,-4 l 1136.5,0 c 2.5,0 7,1 10.5,4 3.5,2.75 4.5,7.5 4.5,10.5 l 0,8 c 0,3.5 -2,7 -4.5,9.5 -2.5,2.5 -6.5,5 -10.5,5 z"
+ id="path4"
+ style="fill:#ffd000;fill-opacity:1;fill-rule:evenodd;stroke:#e0a000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <g
+ transform="translate(1053.75,65.625)"
+ id="g6">
+ <path
+ d="m 79.5,438.5 c 0,4.5 -3.75,8 -8.5,8 -4.5,0 -8.25,-3.5 -8.25,-8 0,-4.5 3.75,-8.25 8.25,-8.25 4.75,0 8.5,3.75 8.5,8.25 l 0,0 z"
+ transform="translate(24,-485)"
+ id="path8"
+ style="fill:#ff4040;fill-opacity:1;fill-rule:nonzero;stroke:#ff4040;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <text
+ id="text10"
+ style="font-size:12px;font-weight:bold;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans">
+ <tspan
+ x="91"
+ y="-42"
+ id="tspan12"
+ style="font-size:12px">X</tspan>
+ </text>
+ </g>
+ <g
+ transform="translate(5.5,0)"
+ id="g14">
+ <path
+ d="M 44,15 10.5,15 27.5,-14 44,15 z"
+ transform="translate(-4,20)"
+ id="path16"
+ style="fill:#404040;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="M 44,15 10.5,15 27.5,-14 44,15 z"
+ transform="translate(1,17)"
+ id="path18"
+ style="fill:#e0e0e0;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="M 44,15 10.5,15 27.5,-14 44,15 z"
+ transform="translate(-1,18)"
+ id="path20"
+ style="fill:#ffe000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ <text
+ x="5.5000076"
+ y="-8.4277344e-06"
+ id="text22"
+ style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans">
+ <tspan
+ x="26.500023"
+ y="28.999992"
+ id="tspan24"
+ style="font-size:24px">!</tspan>
+ </text>
+</svg>
diff --git a/po/TurtleConfusion.pot b/po/TurtleConfusion.pot
index 92799af..747cff2 100644
--- a/po/TurtleConfusion.pot
+++ b/po/TurtleConfusion.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-08-03 10:17-0400\n"
+"POT-Creation-Date: 2011-08-29 09:03-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,271 +17,670 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: activity/activity.info:2 turtleconfusion.py:272
-msgid "Turtle Confusion"
+#: activity/activity.info:2 turtleart.py:272 pysamples/grecord.py:205
+#: TurtleArt/tawindow.py:1568 TurtleArt/tawindow.py:2793
+#: TurtleArt/taexporthtml.py:127 TurtleArt/taexporthtml.py:129
+msgid "Turtle Art"
msgstr ""
-#: turtleconfusion.py:68
+#: turtleart.py:68
msgid "usage is"
msgstr ""
-#: turtleconfusion.py:212
+#: turtleart.py:212
msgid "No option action:"
msgstr ""
-#: turtleconfusion.py:224
+#: turtleart.py:224
msgid "File not found"
msgstr ""
-#: turtleconfusion.py:248
+#: turtleart.py:248
#, python-format
msgid "Configuration directory not writable: %s"
msgstr ""
-#: turtleconfusion.py:304
+#: turtleart.py:304
msgid "New"
msgstr ""
-#: turtleconfusion.py:305
+#: turtleart.py:305
msgid "Open"
msgstr ""
-#: turtleconfusion.py:306
+#: turtleart.py:306
msgid "Save"
msgstr ""
-#: turtleconfusion.py:307
+#: turtleart.py:307
msgid "Save as"
msgstr ""
-#: turtleconfusion.py:308 TurtleConfusionActivity.py:577
+#: turtleart.py:308 TurtleArtActivity.py:604
msgid "Save as image"
msgstr ""
-#: turtleconfusion.py:310
+#: turtleart.py:310 TurtleArtActivity.py:607
msgid "Save as HTML"
msgstr ""
-#: turtleconfusion.py:312 TurtleConfusionActivity.py:574
+#: turtleart.py:312 TurtleArtActivity.py:609
msgid "Save as Logo"
msgstr ""
-#: turtleconfusion.py:314
+#: turtleart.py:314
msgid "Quit"
msgstr ""
-#: turtleconfusion.py:315
+#: turtleart.py:315
msgid "File"
msgstr ""
-#: turtleconfusion.py:318 TurtleConfusionActivity.py:598
+#: turtleart.py:318 TurtleArtActivity.py:539
msgid "Cartesian coordinates"
msgstr ""
-#: turtleconfusion.py:320 TurtleConfusionActivity.py:600
+#: turtleart.py:320 TurtleArtActivity.py:541
msgid "Polar coordinates"
msgstr ""
-#: turtleconfusion.py:322 TurtleConfusionActivity.py:615
+#: turtleart.py:322
+msgid "Rescale coordinates"
+msgstr ""
+
+#: turtleart.py:324 TurtleArtActivity.py:554
msgid "Grow blocks"
msgstr ""
-#: turtleconfusion.py:324 TurtleConfusionActivity.py:618
+#: turtleart.py:326 TurtleArtActivity.py:556
msgid "Shrink blocks"
msgstr ""
-#: turtleconfusion.py:326
+#: turtleart.py:328
msgid "Reset block size"
msgstr ""
-#: turtleconfusion.py:328 TurtleConfusionActivity.py:500
-#: TurtleConfusionActivity.py:547
+#: turtleart.py:330 TurtleArtActivity.py:469 TurtleArtActivity.py:518
msgid "View"
msgstr ""
-#: turtleconfusion.py:331 TurtleConfusionActivity.py:591
+#: turtleart.py:333 TurtleArtActivity.py:533
msgid "Copy"
msgstr ""
-#: turtleconfusion.py:332 TurtleConfusionActivity.py:593
+#: turtleart.py:334 TurtleArtActivity.py:535
msgid "Paste"
msgstr ""
-#: turtleconfusion.py:333 TurtleConfusionActivity.py:496
-#: TurtleConfusionActivity.py:550
+#: turtleart.py:335 TurtleArtActivity.py:465 TurtleArtActivity.py:520
msgid "Edit"
msgstr ""
-#: turtleconfusion.py:336 TurtleConfusionActivity.py:257
+#: turtleart.py:338 TurtleArtActivity.py:244
msgid "Show palette"
msgstr ""
-#: turtleconfusion.py:338 TurtleConfusionActivity.py:263
-#: TurtleConfusionActivity.py:675
+#: turtleart.py:340 TurtleArtActivity.py:250 TurtleArtActivity.py:629
msgid "Hide palette"
msgstr ""
-#: turtleconfusion.py:340
+#: turtleart.py:342
msgid "Show/hide blocks"
msgstr ""
-#: turtleconfusion.py:342
+#: turtleart.py:344
msgid "Tools"
msgstr ""
-#: turtleconfusion.py:345 TurtleConfusionActivity.py:684
+#: turtleart.py:347 TurtleArtActivity.py:638
msgid "Clean"
msgstr ""
-#: turtleconfusion.py:346 TurtleConfusionActivity.py:686
+#: turtleart.py:348 TurtleArtActivity.py:640
msgid "Run"
msgstr ""
-#: turtleconfusion.py:347 TurtleConfusionActivity.py:688
+#: turtleart.py:349 TurtleArtActivity.py:642
msgid "Step"
msgstr ""
-#: turtleconfusion.py:348 TurtleConfusionActivity.py:690
+#: turtleart.py:350 TurtleArtActivity.py:644
msgid "Debug"
msgstr ""
-#: turtleconfusion.py:349
+#: turtleart.py:351
msgid "Stop"
msgstr ""
-#: turtleconfusion.py:350
+#: turtleart.py:352
msgid "Turtle"
msgstr ""
-#: turtleconfusion.py:357
-msgid "Challenge"
-msgstr ""
-
-#: turtleconfusion.py:359
-msgid "Challenges"
-msgstr ""
-
-#: turtleconfusion.py:389
+#: turtleart.py:382
msgid "You have unsaved work. Would you like to save before quitting?"
msgstr ""
-#: turtleconfusion.py:390
+#: turtleart.py:383
msgid "Save project?"
msgstr ""
-#: TurtleConfusionActivity.py:127
+#: TurtleArtActivity.py:125
msgid "presentation"
msgstr ""
-#: TurtleConfusionActivity.py:210
+#: TurtleArtActivity.py:196
msgid "snapshot"
msgstr ""
-#: TurtleConfusionActivity.py:270 TurtleConfusionActivity.py:283
+#: TurtleArtActivity.py:257 TurtleArtActivity.py:270
msgid "Show blocks"
msgstr ""
-#: TurtleConfusionActivity.py:273 TurtleConfusionActivity.py:291
-#: TurtleConfusionActivity.py:678
+#: TurtleArtActivity.py:260 TurtleArtActivity.py:278 TurtleArtActivity.py:632
msgid "Hide blocks"
msgstr ""
-#: TurtleConfusionActivity.py:419
+#: TurtleArtActivity.py:398
msgid "Rescale coordinates down"
msgstr ""
-#: TurtleConfusionActivity.py:423
+#: TurtleArtActivity.py:402 TurtleArtActivity.py:551
msgid "Rescale coordinates up"
msgstr ""
-#: TurtleConfusionActivity.py:440
-msgid "no help available"
+#: TurtleArtActivity.py:476 TurtleArtActivity.py:524
+msgid "Help"
msgstr ""
-#: TurtleConfusionActivity.py:507 TurtleConfusionActivity.py:556
-#: TurtleConfusionActivity.py:621
-msgid "Help"
+#: TurtleArtActivity.py:497 TurtleArtActivity.py:623
+msgid "Load example"
msgstr ""
-#: TurtleConfusionActivity.py:544
+#: TurtleArtActivity.py:516
msgid "Project"
msgstr ""
-#: TurtleConfusionActivity.py:553
+#: TurtleArtActivity.py:522
msgid "Import/Export"
msgstr ""
-#: TurtleConfusionActivity.py:566
-msgid "Save snapshot"
-msgstr ""
-
-#: TurtleConfusionActivity.py:580
-msgid "Import project from the Journal"
-msgstr ""
-
-#: TurtleConfusionActivity.py:595
+#: TurtleArtActivity.py:537
msgid "Fullscreen"
msgstr ""
-#: TurtleConfusionActivity.py:603
+#: TurtleArtActivity.py:544
msgid "Metric coordinates"
msgstr ""
-#: TurtleConfusionActivity.py:606 TurtleArt/tawindow.py:2763
-#: TurtleArt/tawindow.py:2767 TurtleArt/tabasics.py:202
+#: TurtleArtActivity.py:547 TurtleArt/tawindow.py:2789
+#: TurtleArt/tawindow.py:2793 TurtleArt/tabasics.py:216
msgid "xcor"
msgstr ""
-#: TurtleConfusionActivity.py:607 TurtleArt/tawindow.py:2763
-#: TurtleArt/tawindow.py:2767 TurtleArt/tabasics.py:213
+#: TurtleArtActivity.py:548 TurtleArt/tawindow.py:2789
+#: TurtleArt/tawindow.py:2793 TurtleArt/tabasics.py:227
msgid "ycor"
msgstr ""
-#: TurtleConfusionActivity.py:607 TurtleArt/tawindow.py:2763
-#: TurtleArt/tawindow.py:2767 TurtleArt/tabasics.py:224
+#: TurtleArtActivity.py:548 TurtleArt/tawindow.py:2789
+#: TurtleArt/tawindow.py:2793 TurtleArt/tabasics.py:238
msgid "heading"
msgstr ""
-#: TurtleConfusionActivity.py:624 TurtleConfusionActivity.py:628
+#: TurtleArtActivity.py:574 TurtleArtActivity.py:578
msgid "Move the cursor over the orange palette for help."
msgstr ""
-#: TurtleConfusionActivity.py:670
-msgid "Select a challenge"
+#: TurtleArtActivity.py:612
+msgid "Save snapshot"
msgstr ""
-#: TurtleConfusionActivity.py:676
+#: TurtleArtActivity.py:616
+msgid "Import project from the Journal"
+msgstr ""
+
+#: TurtleArtActivity.py:619
+msgid "Load Python block"
+msgstr ""
+
+#: TurtleArtActivity.py:630
msgid "<Ctrl>p"
msgstr ""
-#: TurtleConfusionActivity.py:679
+#: TurtleArtActivity.py:633
msgid "<Ctrl>b"
msgstr ""
-#: TurtleConfusionActivity.py:684
+#: TurtleArtActivity.py:638
msgid "<Ctrl>e"
msgstr ""
-#: TurtleConfusionActivity.py:686
+#: TurtleArtActivity.py:640
msgid "<Ctrl>r"
msgstr ""
-#: TurtleConfusionActivity.py:688
+#: TurtleArtActivity.py:642
msgid "<Ctrl>w"
msgstr ""
-#: TurtleConfusionActivity.py:690
+#: TurtleArtActivity.py:644
msgid "<Ctrl>d"
msgstr ""
-#: TurtleConfusionActivity.py:692
+#: TurtleArtActivity.py:646
msgid "Stop turtle"
msgstr ""
-#: TurtleConfusionActivity.py:693
+#: TurtleArtActivity.py:647
msgid "<Ctrl>s"
msgstr ""
+#: taextras.py:36
+msgid "Turtle Art Mini"
+msgstr ""
+
+#: taextras.py:40
+msgid "Turtle Confusion"
+msgstr ""
+
+#: taextras.py:41
+msgid "Select a challenge"
+msgstr ""
+
+#: taextras.py:47
+msgid "Palette of Mexican pesos"
+msgstr ""
+
+#: taextras.py:48
+msgid "Palette of Colombian pesos"
+msgstr ""
+
+#: taextras.py:49
+msgid "Palette of Rwandan francs"
+msgstr ""
+
+#: taextras.py:50
+msgid "Palette of US currencies"
+msgstr ""
+
+#: taextras.py:51
+msgid "Palette of Australian currencies"
+msgstr ""
+
+#: taextras.py:52
+msgid "Palette of Guaranies"
+msgstr ""
+
+#. TRANS: Butia is the Arduino Robot Project from Uruguay
+#. (http://www.fing.edu.uy/inco/proyectos/butia/)
+#: taextras.py:58
+msgid "Turtle Art Butia"
+msgstr ""
+
+#: taextras.py:59
+msgid "Adjust LED intensity between 0 and 255."
+msgstr ""
+
+#: taextras.py:60
+msgid ""
+"Returns the object gray level encountered him as a number between 0 and 1023."
+msgstr ""
+
+#: taextras.py:62
+msgid "Returns 1 when the button is press and 0 otherwise."
+msgstr ""
+
+#: taextras.py:63
+msgid "Returns the ambient light level as a number between 0 and 1023."
+msgstr ""
+
+#: taextras.py:64
+msgid "Returns the ambient temperature as a number between 0 and 255."
+msgstr ""
+
+#: taextras.py:65
+msgid ""
+"Returns the distance from the object in front of the sensor as a number "
+"between 0 and 255."
+msgstr ""
+
+#: taextras.py:67
+msgid "Returns 0 or 1 depending on the sensor inclination."
+msgstr ""
+
+#: taextras.py:68
+msgid "Returns 1 when the sensors detects a magnetic field, 0 otherwise."
+msgstr ""
+
+#: taextras.py:69
+msgid "Switches from 0 to 1, the frequency depends on the vibration."
+msgstr ""
+
+#: taextras.py:70
+msgid "LED"
+msgstr ""
+
+#: taextras.py:71
+msgid "pushbutton"
+msgstr ""
+
+#: taextras.py:72
+msgid "grayscale"
+msgstr ""
+
+#: taextras.py:73
+msgid "ambient light"
+msgstr ""
+
+#: taextras.py:74
+msgid "temperature"
+msgstr ""
+
+#: taextras.py:75
+msgid "distance"
+msgstr ""
+
+#: taextras.py:76
+msgid "tilt"
+msgstr ""
+
+#: taextras.py:77
+msgid "magnetic induction"
+msgstr ""
+
+#: taextras.py:78
+msgid "vibration"
+msgstr ""
+
+#: taextras.py:79
+msgid "Butia Robot"
+msgstr ""
+
+#: taextras.py:80
+msgid "delay Butia"
+msgstr ""
+
+#: taextras.py:81
+msgid "wait for argument seconds"
+msgstr ""
+
+#: taextras.py:82
+msgid "Butia battery charge"
+msgstr ""
+
+#: taextras.py:83
+msgid "Returns the battery charge as a number between 0 and 255."
+msgstr ""
+
+#: taextras.py:84
+msgid "Butia speed"
+msgstr ""
+
+#: taextras.py:85
+msgid ""
+"Set the speed of the Butia motors as a value between 0 and 1023, passed by "
+"an argument."
+msgstr ""
+
+#: taextras.py:87
+msgid "forward Butia"
+msgstr ""
+
+#: taextras.py:88
+msgid "Move the Butia robot forward."
+msgstr ""
+
+#: taextras.py:89
+msgid "forward distance"
+msgstr ""
+
+#: taextras.py:90
+msgid "Move the Butia robot forward a predefined distance."
+msgstr ""
+
+#: taextras.py:91
+msgid "backward Butia"
+msgstr ""
+
+#: taextras.py:92 taextras.py:96 taextras.py:98 taextras.py:102
+msgid "Move the Butia robot backward."
+msgstr ""
+
+#: taextras.py:93
+msgid "backward distance"
+msgstr ""
+
+#: taextras.py:94
+msgid "Move the Butia robot backward a predefined distance."
+msgstr ""
+
+#: taextras.py:95
+msgid "left Butia"
+msgstr ""
+
+#: taextras.py:97
+msgid "right Butia"
+msgstr ""
+
+#: taextras.py:99
+msgid "Turn x degrees"
+msgstr ""
+
+#: taextras.py:100
+msgid "Turn the Butia robot x degrees."
+msgstr ""
+
+#: taextras.py:101
+msgid "stop Butia"
+msgstr ""
+
+#: taextras.py:103
+msgid "print Butia"
+msgstr ""
+
+#: taextras.py:104
+msgid "Print text in Butia robot 32-character ASCII display."
+msgstr ""
+
+#: taextras.py:105
+msgid "Butia"
+msgstr ""
+
+#: taextras.py:109
+msgid "The camera was not found."
+msgstr ""
+
+#: taextras.py:110
+msgid "Error on the initialization of the camera."
+msgstr ""
+
+#: taextras.py:111
+msgid "FollowMe"
+msgstr ""
+
+#: taextras.py:112
+msgid "follow a RGB color"
+msgstr ""
+
+#: taextras.py:113
+msgid "follow a turtle color"
+msgstr ""
+
+#: taextras.py:114
+msgid "calibrate a color to follow"
+msgstr ""
+
+#: taextras.py:115
+msgid "x position"
+msgstr ""
+
+#: taextras.py:116
+msgid "return x position"
+msgstr ""
+
+#: taextras.py:117
+msgid "y position"
+msgstr ""
+
+#: taextras.py:118
+msgid "return y position"
+msgstr ""
+
+#: taextras.py:122
+msgid "Sumo Butia"
+msgstr ""
+
+#: taextras.py:123
+msgid "submit speed​​"
+msgstr ""
+
+#: taextras.py:124
+msgid "Send speeds the robot."
+msgstr ""
+
+#: taextras.py:125
+msgid "set speed"
+msgstr ""
+
+#: taextras.py:126
+msgid "Set the default speed for the movement commands."
+msgstr ""
+
+#: taextras.py:127
+msgid "move"
+msgstr ""
+
+#: taextras.py:128 TurtleArt/tabasics.py:131
+msgid "back"
+msgstr ""
+
+#: taextras.py:129 pysamples/grecord.py:215
+msgid "stop"
+msgstr ""
+
+#: taextras.py:130
+msgid "turn left"
+msgstr ""
+
+#: taextras.py:131
+msgid "turn right"
+msgstr ""
+
+#: taextras.py:132
+msgid "angle to center"
+msgstr ""
+
+#. TRANS: dojo is the playing field
+#: taextras.py:134
+msgid "Get the angle to the center of the dojo."
+msgstr ""
+
+#: taextras.py:135
+msgid "angle to the opponent"
+msgstr ""
+
+#: taextras.py:136
+msgid "Get the angle to the center of the opponent."
+msgstr ""
+
+#: taextras.py:137
+msgid "x coor."
+msgstr ""
+
+#: taextras.py:138
+msgid "Get the x coordinate of the robot."
+msgstr ""
+
+#: taextras.py:139
+msgid "y coor."
+msgstr ""
+
+#: taextras.py:140
+msgid "Get the y coordinate of the robot."
+msgstr ""
+
+#: taextras.py:141
+msgid "opponent x coor."
+msgstr ""
+
+#: taextras.py:142
+msgid "Get the x coordinate of the opponent."
+msgstr ""
+
+#: taextras.py:143
+msgid "opponent y coor."
+msgstr ""
+
+#: taextras.py:144
+msgid "Get the y coordinate of the opponent."
+msgstr ""
+
+#: taextras.py:145
+msgid "rotation"
+msgstr ""
+
+#: taextras.py:146
+msgid "Get SumBot rotation."
+msgstr ""
+
+#: taextras.py:147
+msgid "opponent rotation"
+msgstr ""
+
+#: taextras.py:148
+msgid "Get the rotation of the opponent."
+msgstr ""
+
+#: taextras.py:149
+msgid "distance to center"
+msgstr ""
+
+#. TRANS: dojo is the playing field
+#: taextras.py:151
+msgid "Get the distance to the center of the dojo."
+msgstr ""
+
+#: taextras.py:152
+msgid "distance to opponent"
+msgstr ""
+
+#: taextras.py:153
+msgid "Get the distance to the opponent."
+msgstr ""
+
+#: taextras.py:154
+msgid "update information"
+msgstr ""
+
+#: taextras.py:155
+msgid "Update information from the server."
+msgstr ""
+
+#: pysamples/grecord.py:205 plugins/audio_sensors/audio_sensors.py:82
+#: plugins/audio_sensors/audio_sensors.py:97
+msgid "sound"
+msgstr ""
+
+#: pysamples/grecord.py:213 TurtleArt/tabasics.py:801
+msgid "start"
+msgstr ""
+
+#: pysamples/grecord.py:217
+msgid "play"
+msgstr ""
+
+#: pysamples/grecord.py:219
+msgid "save"
+msgstr ""
+
+#: pysamples/uturn.py:24
+msgid "uturn"
+msgstr ""
+
+#: pysamples/uturn.py:26
+msgid "make a uturn"
+msgstr ""
+
#: gnome_plugins/collaboration_plugin.py:67
msgid "My Turtle Art session"
msgstr ""
@@ -384,6 +783,604 @@ msgstr ""
msgid "Failed to upload!"
msgstr ""
+#: plugins/camera_sensor/camera_sensor.py:58 plugins/rfid/rfid.py:86
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:269
+#: plugins/light_sensor/light_sensor.py:49
+#: plugins/audio_sensors/audio_sensors.py:75
+#: plugins/accelerometer/accelerometer.py:49
+msgid "Palette of sensor blocks"
+msgstr ""
+
+#: plugins/camera_sensor/camera_sensor.py:69
+#: plugins/camera_sensor/camera_sensor.py:81
+#: plugins/camera_sensor/camera_sensor.py:99
+#: plugins/camera_sensor/camera_sensor.py:112
+#: plugins/light_sensor/light_sensor.py:55
+#: plugins/light_sensor/light_sensor.py:62
+msgid "brightness"
+msgstr ""
+
+#: plugins/camera_sensor/camera_sensor.py:70
+#: plugins/camera_sensor/camera_sensor.py:101
+msgid "light level detected by camera"
+msgstr ""
+
+#: plugins/camera_sensor/camera_sensor.py:82
+#: plugins/camera_sensor/camera_sensor.py:113
+msgid "Average RGB color from camera is pushed to the stack"
+msgstr ""
+
+#: plugins/camera_sensor/camera_sensor.py:93
+#: plugins/camera_sensor/camera_sensor.py:125
+msgid "camera output"
+msgstr ""
+
+#: plugins/rfid/rfid.py:91 plugins/rfid/rfid.py:99
+msgid "RFID"
+msgstr ""
+
+#: plugins/rfid/rfid.py:92 plugins/rfid/rfid.py:100
+msgid "read value from RFID device"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:98
+#: TurtleArt/tabasics.py:707
+msgid "Palette of flow operators"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:103
+msgid "while"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:104
+msgid "do-while-True operator that uses boolean operators from Numbers palette"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:110
+msgid "until"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:111
+msgid "do-until-True operator that uses boolean operators from Numbers palette"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:118
+msgid "Palette of media objects"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:124
+msgid "journal"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:125
+msgid "Sugar Journal media object"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:135
+msgid "audio"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:137
+msgid "Sugar Journal audio object"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:147
+msgid "video"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:149
+msgid "Sugar Journal video object"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:159
+msgid "description"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:161
+msgid "Sugar Journal description field"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:170
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:171
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:172
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:179
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:192
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:207
+#: TurtleArt/tabasics.py:834 TurtleArt/tabasics.py:835
+#: TurtleArt/tabasics.py:836
+msgid "text"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:173
+#: TurtleArt/tabasics.py:837
+msgid "string value"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:178
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:206
+msgid "show"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:182
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:195
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:210
+msgid "draws text or show media from the Journal"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:191
+msgid "show aligned"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:218
+msgid "set scale"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:222
+msgid "sets the scale of media"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:229
+msgid "save picture"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:231
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:242
+msgid "picture name"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:232
+msgid "saves a picture to the Sugar Journal"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:240
+msgid "save SVG"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:243
+msgid "saves turtle graphics as an SVG file in the Sugar Journal"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:250
+msgid "scale"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:254
+msgid "holds current scale value"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:259
+msgid "media wait"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:261
+msgid "wait for current video or audio to complete"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:274
+msgid "query keyboard"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:276
+msgid "query for keyboard input (results stored in keyboard block)"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:283
+msgid "keyboard"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:287
+msgid "holds results of query-keyboard block"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:294
+msgid "read pixel"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:297
+msgid "RGB color under the turtle is pushed to the stack"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:305
+msgid "turtle sees"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:307
+msgid "returns the color that the turtle \"sees\""
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:315
+msgid "time"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:318
+msgid "elapsed time (in seconds) since program started"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:327
+msgid "Palette of extra options"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:332
+msgid "push"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:335
+msgid "pushes value onto FILO (first-in last-out heap)"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:345
+msgid "show heap"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:348
+msgid "shows values in FILO (first-in last-out heap)"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:358
+msgid "empty heap"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:361
+msgid "emptys FILO (first-in-last-out heap)"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:371
+msgid "pop"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:375
+msgid "pops value off FILO (first-in last-out heap)"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:385
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:387
+msgid "comment"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:388
+msgid "places a comment in your code"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:394
+msgid "print"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:397
+msgid "prints value in status block at bottom of the screen"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:405
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:417
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:430
+msgid "Python"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:408
+msgid ""
+"a programmable block: used to add advanced single-variable math equations, e."
+"g., sin(x)"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:420
+msgid ""
+"a programmable block: used to add advanced multi-variable math equations, e."
+"g., sqrt(x*x+y*y)"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:433
+msgid ""
+"a programmable block: used to add advanced multi-variable math equations, e."
+"g., sin(x+y+z)"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:444
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:459
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:474
+msgid "Python block"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:446
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:461
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:476
+msgid "runs code found in the tamyblock.py module found in the Journal"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:489
+msgid "Cartesian"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:491
+msgid "displays Cartesian coordinates"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:497
+msgid "polar"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:499
+msgid "displays polar coordinates"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:505
+msgid "turtle"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:508
+msgid "chooses which turtle to command"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:517
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:526
+msgid "turtle shell"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:519
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:527
+msgid "put a custom 'shell' on the turtle"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:532
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:697
+msgid "top"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:534
+msgid "top of a collapsed stack"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:540
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:673
+msgid "bottom"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:541
+msgid "bottom of a collapsible stack"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:549
+msgid "bottom block in a collapsed stack: click to open"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:557
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:560
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:569
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:577
+msgid "top of stack"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:558
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:567
+msgid "label"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:566
+msgid "top of a collapsible stack"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:575
+#: TurtleArt/tautils.py:590
+msgid "click to open"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:583
+msgid "Palette of presentation templates"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:587
+msgid "hide blocks"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:589
+msgid "declutters canvas by hiding blocks"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:594
+msgid "show blocks"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:596
+msgid "restores hidden blocks"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:601
+msgid "full screen"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:603
+msgid "hides the Sugar toolbars"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:612
+msgid "list"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:615
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:845
+msgid "presentation bulleted list"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:623
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:846
+msgid "presentation template: list of bullets"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:630
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:790
+msgid "presentation template: select Journal object (no description)"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:637
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:776
+msgid "presentation template: select Journal object (with description)"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:644
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:832
+msgid "presentation template: select four Journal objects"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:651
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:658
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:804
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:818
+msgid "presentation template: select two Journal objects"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:665
+#: TurtleArt/tabasics.py:154
+msgid "left"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:668
+msgid "xcor of left of screen"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:676
+msgid "ycor of bottom of screen"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:681
+msgid "width"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:684
+msgid "the canvas width"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:689
+#: TurtleArt/tabasics.py:165
+msgid "right"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:692
+msgid "xcor of right of screen"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:700
+msgid "ycor of top of screen"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:705
+msgid "height"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:708
+msgid "the canvas height"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:715
+msgid "title x"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:724
+msgid "title y"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:733
+msgid "left x"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:742
+msgid "top y"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:751
+msgid "right x"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:760
+msgid "bottom y"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:774
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:788
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:802
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:816
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:830
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:844
+#: TurtleArt/taconstants.py:251 TurtleArt/taconstants.py:273
+#: TurtleArt/taconstants.py:294 TurtleArt/taconstants.py:336
+#: TurtleArt/taconstants.py:378 TurtleArt/taconstants.py:420
+msgid "Title"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:775
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:789
+msgid "presentation 1x1"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:803
+msgid "presentation 2x1"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:817
+msgid "presentation 1x2"
+msgstr ""
+
+#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:831
+msgid "presentation 2x2"
+msgstr ""
+
+#: plugins/light_sensor/light_sensor.py:57
+#: plugins/light_sensor/light_sensor.py:64
+msgid "light level detected by light sensor"
+msgstr ""
+
+#: plugins/audio_sensors/audio_sensors.py:83
+#: plugins/audio_sensors/audio_sensors.py:98
+msgid "raw microphone input signal"
+msgstr ""
+
+#: plugins/audio_sensors/audio_sensors.py:89
+#: plugins/audio_sensors/audio_sensors.py:104
+msgid "loudness"
+msgstr ""
+
+#: plugins/audio_sensors/audio_sensors.py:90
+#: plugins/audio_sensors/audio_sensors.py:105
+msgid "microphone input volume"
+msgstr ""
+
+#: plugins/audio_sensors/audio_sensors.py:118
+#: plugins/audio_sensors/audio_sensors.py:126
+msgid "pitch"
+msgstr ""
+
+#: plugins/audio_sensors/audio_sensors.py:119
+#: plugins/audio_sensors/audio_sensors.py:127
+msgid "microphone input pitch"
+msgstr ""
+
+#: plugins/audio_sensors/audio_sensors.py:145
+#: plugins/audio_sensors/audio_sensors.py:159
+msgid "resistance"
+msgstr ""
+
+#: plugins/audio_sensors/audio_sensors.py:146
+#: plugins/audio_sensors/audio_sensors.py:160
+msgid "microphone input resistance"
+msgstr ""
+
+#: plugins/audio_sensors/audio_sensors.py:151
+#: plugins/audio_sensors/audio_sensors.py:166
+msgid "voltage"
+msgstr ""
+
+#: plugins/audio_sensors/audio_sensors.py:152
+#: plugins/audio_sensors/audio_sensors.py:167
+msgid "microphone input voltage"
+msgstr ""
+
+#: plugins/accelerometer/accelerometer.py:55
+#: plugins/accelerometer/accelerometer.py:62
+msgid "acceleration"
+msgstr ""
+
+#: plugins/accelerometer/accelerometer.py:57
+#: plugins/accelerometer/accelerometer.py:64
+msgid "push acceleration in x, y, z to heap"
+msgstr ""
+
#: TurtleArt/tapalette.py:83
msgid "displays next palette"
msgstr ""
@@ -392,20 +1389,15 @@ msgstr ""
msgid "changes the orientation of the palette of blocks"
msgstr ""
-#: TurtleArt/tawindow.py:737 TurtleArt/tawindow.py:738
+#: TurtleArt/tawindow.py:748 TurtleArt/tawindow.py:749
msgid "orientation"
msgstr ""
-#: TurtleArt/tawindow.py:748 TurtleArt/tawindow.py:1010
+#: TurtleArt/tawindow.py:759 TurtleArt/tawindow.py:1022
msgid "next"
msgstr ""
-#: TurtleArt/tawindow.py:1549 TurtleArt/tawindow.py:2767
-#: TurtleArt/taexporthtml.py:127 TurtleArt/taexporthtml.py:129
-msgid "Turtle Art"
-msgstr ""
-
-#: TurtleArt/tawindow.py:2859
+#: TurtleArt/tawindow.py:2885
msgid "image"
msgstr ""
@@ -417,16 +1409,6 @@ msgstr ""
msgid "Save..."
msgstr ""
-#: TurtleArt/tautils.py:587
-msgid "click to open"
-msgstr ""
-
-#: TurtleArt/taconstants.py:255 TurtleArt/taconstants.py:277
-#: TurtleArt/taconstants.py:298 TurtleArt/taconstants.py:340
-#: TurtleArt/taconstants.py:382 TurtleArt/taconstants.py:424
-msgid "Title"
-msgstr ""
-
#: TurtleArt/talogo.py:417
msgid "did not output to"
msgstr ""
@@ -435,11 +1417,11 @@ msgstr ""
msgid "I don't know how to"
msgstr ""
-#: TurtleArt/talogo.py:515
+#: TurtleArt/talogo.py:512
msgid "doesn't like"
msgstr ""
-#: TurtleArt/talogo.py:515
+#: TurtleArt/talogo.py:512
msgid "as input"
msgstr ""
@@ -455,10 +1437,6 @@ msgstr ""
msgid "moves turtle forward"
msgstr ""
-#: TurtleArt/tabasics.py:131
-msgid "back"
-msgstr ""
-
#: TurtleArt/tabasics.py:135
msgid "moves turtle backward"
msgstr ""
@@ -471,568 +1449,539 @@ msgstr ""
msgid "clears the screen and reset the turtle"
msgstr ""
-#: TurtleArt/tabasics.py:154
-msgid "left"
-msgstr ""
-
#: TurtleArt/tabasics.py:158
msgid "turns turtle counterclockwise (angle in degrees)"
msgstr ""
-#: TurtleArt/tabasics.py:165
-msgid "right"
-msgstr ""
-
#: TurtleArt/tabasics.py:169
msgid "turns turtle clockwise (angle in degrees)"
msgstr ""
-#: TurtleArt/tabasics.py:176 TurtleArt/tabasics.py:258
+#: TurtleArt/tabasics.py:177
+msgid "arc"
+msgstr ""
+
+#: TurtleArt/tabasics.py:177
+msgid "angle"
+msgstr ""
+
+#: TurtleArt/tabasics.py:177
+msgid "radius"
+msgstr ""
+
+#: TurtleArt/tabasics.py:181
+msgid "moves turtle along an arc"
+msgstr ""
+
+#: TurtleArt/tabasics.py:190 TurtleArt/tabasics.py:256
msgid "set xy"
msgstr ""
-#: TurtleArt/tabasics.py:176 TurtleArt/tabasics.py:258
+#: TurtleArt/tabasics.py:190 TurtleArt/tabasics.py:256
msgid "x"
msgstr ""
-#: TurtleArt/tabasics.py:176 TurtleArt/tabasics.py:258
+#: TurtleArt/tabasics.py:190 TurtleArt/tabasics.py:256
msgid "y"
msgstr ""
-#: TurtleArt/tabasics.py:180 TurtleArt/tabasics.py:262
+#: TurtleArt/tabasics.py:194 TurtleArt/tabasics.py:260
msgid ""
"moves turtle to position xcor, ycor; (0, 0) is in the center of the screen."
msgstr ""
-#: TurtleArt/tabasics.py:190
+#: TurtleArt/tabasics.py:204
msgid "set heading"
msgstr ""
-#: TurtleArt/tabasics.py:194
+#: TurtleArt/tabasics.py:208
msgid "sets the heading of the turtle (0 is towards the top of the screen.)"
msgstr ""
-#: TurtleArt/tabasics.py:203
+#: TurtleArt/tabasics.py:217
msgid ""
"holds current x-coordinate value of the turtle (can be used in place of a "
"number block)"
msgstr ""
-#: TurtleArt/tabasics.py:214
+#: TurtleArt/tabasics.py:228
msgid ""
"holds current y-coordinate value of the turtle (can be used in place of a "
"number block)"
msgstr ""
-#: TurtleArt/tabasics.py:225
+#: TurtleArt/tabasics.py:239
msgid ""
"holds current heading value of the turtle (can be used in place of a number "
"block)"
msgstr ""
-#: TurtleArt/tabasics.py:244
-msgid "arc"
-msgstr ""
-
-#: TurtleArt/tabasics.py:244
-msgid "angle"
-msgstr ""
-
-#: TurtleArt/tabasics.py:244
-msgid "radius"
-msgstr ""
-
-#: TurtleArt/tabasics.py:248
-msgid "moves turtle along an arc"
-msgstr ""
-
-#: TurtleArt/tabasics.py:275
+#: TurtleArt/tabasics.py:273
msgid "Palette of pen commands"
msgstr ""
-#: TurtleArt/tabasics.py:279
+#: TurtleArt/tabasics.py:277
msgid "pen up"
msgstr ""
-#: TurtleArt/tabasics.py:282
+#: TurtleArt/tabasics.py:280
msgid "Turtle will not draw when moved."
msgstr ""
-#: TurtleArt/tabasics.py:288
+#: TurtleArt/tabasics.py:286
msgid "pen down"
msgstr ""
-#: TurtleArt/tabasics.py:291
+#: TurtleArt/tabasics.py:289
msgid "Turtle will draw when moved."
msgstr ""
-#: TurtleArt/tabasics.py:299
+#: TurtleArt/tabasics.py:295
msgid "set pen size"
msgstr ""
-#: TurtleArt/tabasics.py:303
+#: TurtleArt/tabasics.py:299
msgid "sets size of the line drawn by the turtle"
msgstr ""
-#: TurtleArt/tabasics.py:314
+#: TurtleArt/tabasics.py:309
msgid "fill screen"
msgstr ""
-#: TurtleArt/tabasics.py:314 TurtleArt/tabasics.py:404
+#: TurtleArt/tabasics.py:309 TurtleArt/tabasics.py:394
msgid "color"
msgstr ""
-#: TurtleArt/tabasics.py:314 TurtleArt/tabasics.py:415
+#: TurtleArt/tabasics.py:309 TurtleArt/tabasics.py:404
msgid "shade"
msgstr ""
-#: TurtleArt/tabasics.py:318
+#: TurtleArt/tabasics.py:313
msgid "fills the background with (color, shade)"
msgstr ""
-#: TurtleArt/tabasics.py:328
+#: TurtleArt/tabasics.py:322
msgid "pen size"
msgstr ""
-#: TurtleArt/tabasics.py:329
+#: TurtleArt/tabasics.py:323
msgid "holds current pen size (can be used in place of a number block)"
msgstr ""
-#: TurtleArt/tabasics.py:341
+#: TurtleArt/tabasics.py:334
msgid "start fill"
msgstr ""
-#: TurtleArt/tabasics.py:343
+#: TurtleArt/tabasics.py:336
msgid "starts filled polygon (used with end fill block)"
msgstr ""
-#: TurtleArt/tabasics.py:351
+#: TurtleArt/tabasics.py:343
msgid "end fill"
msgstr ""
-#: TurtleArt/tabasics.py:353
+#: TurtleArt/tabasics.py:345
msgid "completes filled polygon (used with start fill block)"
msgstr ""
-#: TurtleArt/tabasics.py:363
+#: TurtleArt/tabasics.py:355
msgid "Palette of pen colors"
msgstr ""
-#: TurtleArt/tabasics.py:367
+#: TurtleArt/tabasics.py:359
msgid "set color"
msgstr ""
-#: TurtleArt/tabasics.py:371
+#: TurtleArt/tabasics.py:363
msgid "sets color of the line drawn by the turtle"
msgstr ""
-#: TurtleArt/tabasics.py:380
+#: TurtleArt/tabasics.py:371
msgid "set shade"
msgstr ""
-#: TurtleArt/tabasics.py:384
+#: TurtleArt/tabasics.py:375
msgid "sets shade of the line drawn by the turtle"
msgstr ""
-#: TurtleArt/tabasics.py:393
+#: TurtleArt/tabasics.py:383
msgid "set gray"
msgstr ""
-#: TurtleArt/tabasics.py:396
+#: TurtleArt/tabasics.py:386
msgid "sets gray level of the line drawn by the turtle"
msgstr ""
-#: TurtleArt/tabasics.py:405
+#: TurtleArt/tabasics.py:395
msgid "holds current pen color (can be used in place of a number block)"
msgstr ""
-#: TurtleArt/tabasics.py:416
+#: TurtleArt/tabasics.py:405
msgid "holds current pen shade"
msgstr ""
-#: TurtleArt/tabasics.py:425
+#: TurtleArt/tabasics.py:413
msgid "gray"
msgstr ""
-#: TurtleArt/tabasics.py:426
+#: TurtleArt/tabasics.py:414
msgid "holds current gray level (can be used in place of a number block)"
msgstr ""
-#: TurtleArt/tabasics.py:446
+#: TurtleArt/tabasics.py:434
msgid "set text color"
msgstr ""
-#: TurtleArt/tabasics.py:449
+#: TurtleArt/tabasics.py:437
msgid "sets color of text drawn by the turtle"
msgstr ""
-#: TurtleArt/tabasics.py:457
+#: TurtleArt/tabasics.py:445
msgid "set text size"
msgstr ""
-#: TurtleArt/tabasics.py:460
+#: TurtleArt/tabasics.py:448
msgid "sets size of text drawn by the turtle"
msgstr ""
-#: TurtleArt/tabasics.py:543
+#: TurtleArt/tabasics.py:531
msgid "Palette of numeric operators"
msgstr ""
-#: TurtleArt/tabasics.py:549
+#: TurtleArt/tabasics.py:537
msgid "plus"
msgstr ""
-#: TurtleArt/tabasics.py:552
+#: TurtleArt/tabasics.py:540
msgid "adds two alphanumeric inputs"
msgstr ""
-#: TurtleArt/tabasics.py:560
+#: TurtleArt/tabasics.py:548
msgid "minus"
msgstr ""
-#: TurtleArt/tabasics.py:563
+#: TurtleArt/tabasics.py:551
msgid "subtracts bottom numeric input from top numeric input"
msgstr ""
-#: TurtleArt/tabasics.py:574
+#: TurtleArt/tabasics.py:562
msgid "multiply"
msgstr ""
-#: TurtleArt/tabasics.py:577
+#: TurtleArt/tabasics.py:565
msgid "multiplies two numeric inputs"
msgstr ""
-#: TurtleArt/tabasics.py:586
+#: TurtleArt/tabasics.py:574
msgid "divide"
msgstr ""
-#: TurtleArt/tabasics.py:589
+#: TurtleArt/tabasics.py:577
msgid ""
"divides top numeric input (numerator) by bottom numeric input (denominator)"
msgstr ""
-#: TurtleArt/tabasics.py:599
+#: TurtleArt/tabasics.py:587
msgid "identity"
msgstr ""
-#: TurtleArt/tabasics.py:601
+#: TurtleArt/tabasics.py:589
msgid "identity operator used for extending blocks"
msgstr ""
-#: TurtleArt/tabasics.py:609 TurtleArt/tabasics.py:610
+#: TurtleArt/tabasics.py:597 TurtleArt/tabasics.py:598
msgid "mod"
msgstr ""
-#: TurtleArt/tabasics.py:613
+#: TurtleArt/tabasics.py:601
msgid "modular (remainder) operator"
msgstr ""
-#: TurtleArt/tabasics.py:621
+#: TurtleArt/tabasics.py:608
msgid "√"
msgstr ""
-#: TurtleArt/tabasics.py:622
+#: TurtleArt/tabasics.py:609
msgid "square root"
msgstr ""
-#: TurtleArt/tabasics.py:625
+#: TurtleArt/tabasics.py:612
msgid "calculates square root"
msgstr ""
-#: TurtleArt/tabasics.py:633
+#: TurtleArt/tabasics.py:619
msgid "random"
msgstr ""
-#: TurtleArt/tabasics.py:633
+#: TurtleArt/tabasics.py:619
msgid "min"
msgstr ""
-#: TurtleArt/tabasics.py:633
+#: TurtleArt/tabasics.py:619
msgid "max"
msgstr ""
-#: TurtleArt/tabasics.py:637
+#: TurtleArt/tabasics.py:623
msgid "returns random number between minimum (top) and maximum (bottom) values"
msgstr ""
-#: TurtleArt/tabasics.py:649
+#: TurtleArt/tabasics.py:635
msgid "number"
msgstr ""
-#: TurtleArt/tabasics.py:650
+#: TurtleArt/tabasics.py:636
msgid "used as numeric input in mathematic operators"
msgstr ""
-#: TurtleArt/tabasics.py:658
+#: TurtleArt/tabasics.py:643
msgid "greater than"
msgstr ""
-#: TurtleArt/tabasics.py:661
+#: TurtleArt/tabasics.py:646
msgid "logical greater-than operator"
msgstr ""
-#: TurtleArt/tabasics.py:670
+#: TurtleArt/tabasics.py:654
msgid "less than"
msgstr ""
-#: TurtleArt/tabasics.py:673
+#: TurtleArt/tabasics.py:657
msgid "logical less-than operator"
msgstr ""
-#: TurtleArt/tabasics.py:682
+#: TurtleArt/tabasics.py:665
msgid "equal"
msgstr ""
-#: TurtleArt/tabasics.py:685
+#: TurtleArt/tabasics.py:668
msgid "logical equal-to operator"
msgstr ""
-#: TurtleArt/tabasics.py:692
+#: TurtleArt/tabasics.py:674
msgid "not"
msgstr ""
-#: TurtleArt/tabasics.py:695
+#: TurtleArt/tabasics.py:677
msgid "logical NOT operator"
msgstr ""
-#: TurtleArt/tabasics.py:702 TurtleArt/tabasics.py:705
+#: TurtleArt/tabasics.py:683 TurtleArt/tabasics.py:686
msgid "and"
msgstr ""
-#: TurtleArt/tabasics.py:706
+#: TurtleArt/tabasics.py:687
msgid "logical AND operator"
msgstr ""
-#: TurtleArt/tabasics.py:714 TurtleArt/tabasics.py:717
+#: TurtleArt/tabasics.py:694 TurtleArt/tabasics.py:697
msgid "or"
msgstr ""
-#: TurtleArt/tabasics.py:718
+#: TurtleArt/tabasics.py:698
msgid "logical OR operator"
msgstr ""
-#: TurtleArt/tabasics.py:727
-msgid "Palette of flow operators"
-msgstr ""
-
-#: TurtleArt/tabasics.py:733
+#: TurtleArt/tabasics.py:712
msgid "wait"
msgstr ""
-#: TurtleArt/tabasics.py:737
+#: TurtleArt/tabasics.py:716
msgid "pauses program execution a specified number of seconds"
msgstr ""
-#: TurtleArt/tabasics.py:745
+#: TurtleArt/tabasics.py:723
msgid "forever"
msgstr ""
-#: TurtleArt/tabasics.py:749
+#: TurtleArt/tabasics.py:727
msgid "loops forever"
msgstr ""
-#: TurtleArt/tabasics.py:755 TurtleArt/tabasics.py:759
+#: TurtleArt/tabasics.py:733 TurtleArt/tabasics.py:737
msgid "repeat"
msgstr ""
-#: TurtleArt/tabasics.py:760
+#: TurtleArt/tabasics.py:738
msgid "loops specified number of times"
msgstr ""
-#: TurtleArt/tabasics.py:767 TurtleArt/tabasics.py:780
+#: TurtleArt/tabasics.py:744 TurtleArt/tabasics.py:756
msgid "if"
msgstr ""
-#: TurtleArt/tabasics.py:767
+#: TurtleArt/tabasics.py:744
msgid "then"
msgstr ""
-#: TurtleArt/tabasics.py:770
+#: TurtleArt/tabasics.py:747
msgid "if then"
msgstr ""
-#: TurtleArt/tabasics.py:772
+#: TurtleArt/tabasics.py:749
msgid "if-then operator that uses boolean operators from Numbers palette"
msgstr ""
-#: TurtleArt/tabasics.py:780
+#: TurtleArt/tabasics.py:756
msgid "then else"
msgstr ""
-#: TurtleArt/tabasics.py:784
+#: TurtleArt/tabasics.py:760
msgid "if then else"
msgstr ""
-#: TurtleArt/tabasics.py:785
+#: TurtleArt/tabasics.py:761
msgid "if-then-else operator that uses boolean operators from Numbers palette"
msgstr ""
-#: TurtleArt/tabasics.py:794
+#: TurtleArt/tabasics.py:769
msgid "horizontal space"
msgstr ""
-#: TurtleArt/tabasics.py:795
+#: TurtleArt/tabasics.py:770
msgid "jogs stack right"
msgstr ""
-#: TurtleArt/tabasics.py:802
+#: TurtleArt/tabasics.py:777
msgid "vertical space"
msgstr ""
-#: TurtleArt/tabasics.py:803
+#: TurtleArt/tabasics.py:778
msgid "jogs stack down"
msgstr ""
-#: TurtleArt/tabasics.py:810
+#: TurtleArt/tabasics.py:784
msgid "stop action"
msgstr ""
-#: TurtleArt/tabasics.py:813
+#: TurtleArt/tabasics.py:787
msgid "stops current action"
msgstr ""
-#: TurtleArt/tabasics.py:822
+#: TurtleArt/tabasics.py:796
msgid "Palette of variable blocks"
msgstr ""
-#: TurtleArt/tabasics.py:827
-msgid "start"
-msgstr ""
-
-#: TurtleArt/tabasics.py:830
+#: TurtleArt/tabasics.py:804
msgid "connects action to toolbar run buttons"
msgstr ""
-#: TurtleArt/tabasics.py:838
+#: TurtleArt/tabasics.py:812
msgid "store in box 1"
msgstr ""
-#: TurtleArt/tabasics.py:842
+#: TurtleArt/tabasics.py:816
msgid "stores numeric value in Variable 1"
msgstr ""
-#: TurtleArt/tabasics.py:849
+#: TurtleArt/tabasics.py:823
msgid "store in box 2"
msgstr ""
-#: TurtleArt/tabasics.py:853
+#: TurtleArt/tabasics.py:827
msgid "stores numeric value in Variable 2"
msgstr ""
-#: TurtleArt/tabasics.py:861 TurtleArt/tabasics.py:862
-#: TurtleArt/tabasics.py:863
-msgid "text"
-msgstr ""
-
-#: TurtleArt/tabasics.py:864
-msgid "string value"
-msgstr ""
-
-#: TurtleArt/tabasics.py:868
+#: TurtleArt/tabasics.py:841
msgid "box 1"
msgstr ""
-#: TurtleArt/tabasics.py:871
+#: TurtleArt/tabasics.py:844
msgid "Variable 1 (numeric value)"
msgstr ""
-#: TurtleArt/tabasics.py:877
+#: TurtleArt/tabasics.py:850
msgid "box 2"
msgstr ""
-#: TurtleArt/tabasics.py:880
+#: TurtleArt/tabasics.py:853
msgid "Variable 2 (numeric value)"
msgstr ""
-#: TurtleArt/tabasics.py:888 TurtleArt/tabasics.py:899
+#: TurtleArt/tabasics.py:860 TurtleArt/tabasics.py:870
msgid "box"
msgstr ""
-#: TurtleArt/tabasics.py:890 TurtleArt/tabasics.py:902
+#: TurtleArt/tabasics.py:862 TurtleArt/tabasics.py:873
msgid "my box"
msgstr ""
-#: TurtleArt/tabasics.py:892
+#: TurtleArt/tabasics.py:864
msgid "named variable (numeric value)"
msgstr ""
-#: TurtleArt/tabasics.py:899
+#: TurtleArt/tabasics.py:870
msgid "store in"
msgstr ""
-#: TurtleArt/tabasics.py:899
+#: TurtleArt/tabasics.py:870
msgid "value"
msgstr ""
-#: TurtleArt/tabasics.py:903
+#: TurtleArt/tabasics.py:874
msgid "stores numeric value in named variable"
msgstr ""
-#: TurtleArt/tabasics.py:912 TurtleArt/tabasics.py:939
-#: TurtleArt/tabasics.py:942
+#: TurtleArt/tabasics.py:882 TurtleArt/tabasics.py:884
+#: TurtleArt/tabasics.py:908 TurtleArt/tabasics.py:911
msgid "action"
msgstr ""
-#: TurtleArt/tabasics.py:914
-msgid "stack"
-msgstr ""
-
-#: TurtleArt/tabasics.py:916
+#: TurtleArt/tabasics.py:886
msgid "top of nameable action stack"
msgstr ""
-#: TurtleArt/tabasics.py:921 TurtleArt/tabasics.py:949
+#: TurtleArt/tabasics.py:891 TurtleArt/tabasics.py:918
msgid "action 1"
msgstr ""
-#: TurtleArt/tabasics.py:924
+#: TurtleArt/tabasics.py:894
msgid "top of Action 1 stack"
msgstr ""
-#: TurtleArt/tabasics.py:929 TurtleArt/tabasics.py:958
+#: TurtleArt/tabasics.py:899 TurtleArt/tabasics.py:927
msgid "action 2"
msgstr ""
-#: TurtleArt/tabasics.py:932
+#: TurtleArt/tabasics.py:902
msgid "top of Action 2 stack"
msgstr ""
-#: TurtleArt/tabasics.py:943
+#: TurtleArt/tabasics.py:912
msgid "invokes named action stack"
msgstr ""
-#: TurtleArt/tabasics.py:952
+#: TurtleArt/tabasics.py:921
msgid "invokes Action 1 stack"
msgstr ""
-#: TurtleArt/tabasics.py:961
+#: TurtleArt/tabasics.py:930
msgid "invokes Action 2 stack"
msgstr ""
-#: TurtleArt/tabasics.py:969
+#: TurtleArt/tabasics.py:938
msgid "trash"
msgstr ""
-#: TurtleArt/tabasics.py:973
+#: TurtleArt/tabasics.py:942
msgid "empty trash"
msgstr ""
-#: TurtleArt/tabasics.py:974
+#: TurtleArt/tabasics.py:943
msgid "permanently deletes items in trash"
msgstr ""
-#: TurtleArt/tabasics.py:978
+#: TurtleArt/tabasics.py:947
msgid "restore all"
msgstr ""
-#: TurtleArt/tabasics.py:979
+#: TurtleArt/tabasics.py:948
msgid "restore all blocks from trash"
msgstr ""
-#: TurtleArt/tabasics.py:983
+#: TurtleArt/tabasics.py:952
msgid "clear all"
msgstr ""
-#: TurtleArt/tabasics.py:984
+#: TurtleArt/tabasics.py:953
msgid "move all blocks to trash"
msgstr ""
diff --git a/turtleconfusion.py b/turtleconfusion.py
index 0cff962..e639e38 100755
--- a/turtleconfusion.py
+++ b/turtleconfusion.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#Copyright (c) 2007-8, Playful Invention Company
-#Copyright (c) 2008-11, Walter Bender
+#Copyright (c) 2008-12, Walter Bender
#Copyright (c) 2011 Collabora Ltd. <http://www.collabora.co.uk/>
#Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -32,6 +32,7 @@ import os
import os.path
import cStringIO
import errno
+import ConfigParser
try:
# Try to use XDG Base Directory standard for config files.
@@ -51,8 +52,7 @@ import gettext
# from a git repository or the unzipped .xo file.
# gettext.bindtextdomain('org.laptop.TurtleArtActivity', 'locale')
-gettext.textdomain('org.laptop.TurtleArtActivity')
-_ = gettext.gettext
+import gettext
from TurtleArt.taconstants import OVERLAY_LAYER, DEFAULT_TURTLE_COLORS
from TurtleArt.tautils import data_to_string, data_from_string, get_save_name
@@ -64,13 +64,7 @@ from util.menubuilder import MenuBuilder
class TurtleMain():
- ''' Launch Turtle Art from outside of Sugar. '''
-
- _HELP_MSG = 'turtleart.py: ' + _('usage is') + '''
- \tturtleart.py
- \tturtleart.py project.ta
- \tturtleart.py --output_png project.ta
- \tturtleart.py -o project'''
+ ''' Launch Turtle Confusion from outside of Sugar. '''
_INSTALL_PATH = '/usr/share/sugar/activities/TurtleArt.activity'
_ALTERNATIVE_INSTALL_PATH = \
'/usr/local/share/sugar/activities/TurtleArt.activity'
@@ -78,12 +72,30 @@ class TurtleMain():
_GNOME_PLUGIN_SUBPATH = 'gnome_plugins'
def __init__(self):
+ self._abspath = os.path.abspath('.')
+ self._execdirname = self._get_execution_dir()
+ if self._execdirname is not None:
+ os.chdir(self._execdirname)
+ file_activity_info = ConfigParser.ConfigParser()
+ activity_info_path = os.path.abspath('./activity/activity.info')
+ file_activity_info.read(activity_info_path)
+ bundle_id = file_activity_info.get('Activity', 'bundle_id')
+ gettext.textdomain(bundle_id)
+ global _
+ _ = gettext.gettext
+ self._HELP_MSG = 'turtleart.py: ' + _('usage is') + '''
+ \tturtleconfusion.py
+ \tturtleconfusion.py project.ta
+ \tturtleconfusion.py --output_png project.ta
+ \tturtleconfusion.py -o project
+ \tturtleconfusion.py --run project.ta
+ \tturtleconfusion.py -r project'''
self._init_vars()
self._parse_command_line()
self._ensure_sugar_paths()
self._plugins = []
- if self.output_png:
+ if self._output_png:
# Fix me: We need to create a cairo surface to work with
pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8,
gtk.gdk.screen_width(),
@@ -105,9 +117,9 @@ class TurtleMain():
def _get_gnome_plugin_home(self):
''' Use plugin directory associated with execution path. '''
- if os.path.exists(os.path.join(self._dirname,
+ if os.path.exists(os.path.join(self._execdirname,
self._GNOME_PLUGIN_SUBPATH)):
- return os.path.join(self._dirname, self._GNOME_PLUGIN_SUBPATH)
+ return os.path.join(self._execdirname, self._GNOME_PLUGIN_SUBPATH)
else:
return None
@@ -162,22 +174,23 @@ class TurtleMain():
''' Get a main window set up. '''
self.win.connect('configure_event', self.tw.update_overlay_position)
self.tw.parent = self.win
- if self.ta_file is None:
+ if self._ta_file is None:
self.tw.load_start()
else:
- print self.ta_file
- self.tw.load_start(self.ta_file)
+ print self._ta_file
+ self.tw.load_start(self._ta_file)
self.tw.lc.trace = 0
- self.tw.run_button(0)
+ if self._run_on_launch:
+ self._do_run_cb()
gtk.main()
def _draw_and_quit(self):
''' Non-interactive mode: run the project, save it to a file
and quit. '''
- self.tw.load_start(self.ta_file)
+ self.tw.load_start(self._ta_file)
self.tw.lc.trace = 0
self.tw.run_button(0)
- self.tw.save_as_image(self.ta_file)
+ self.tw.save_as_image(self._ta_file)
def _build_window(self, interactive=True):
''' Initialize the TurtleWindow instance. '''
@@ -193,18 +206,15 @@ class TurtleMain():
self.turtle_canvas = surface.create_similar(
cairo.CONTENT_COLOR, gtk.gdk.screen_width() * 2,
gtk.gdk.screen_height() * 2)
- self.tw = TurtleArtWindow(self.canvas, self._dirname,
+ self.tw = TurtleArtWindow(self.canvas, self._execdirname,
turtle_canvas=self.turtle_canvas)
self.tw.save_folder = os.path.expanduser('~')
def _init_vars(self):
''' If we are invoked to start a project from Gnome, we should make
sure our current directory is TA's source dir. '''
- self._dirname = self._get_execution_dir()
- if self._dirname is not None:
- os.chdir(self._dirname)
- self.ta_file = None
- self.output_png = False
+ self._ta_file = None
+ self._output_png = False
self.i = 0 # FIXME: use a better name for this variable
self.scale = 2.0
self.tw = None
@@ -212,32 +222,35 @@ class TurtleMain():
def _parse_command_line(self):
''' Try to make sense of the command-line arguments. '''
try:
- opts, args = getopt.getopt(argv[1:], 'ho',
- ['help', 'output_png'])
+ opts, args = getopt.getopt(argv[1:], 'hor',
+ ['help', '_output_png', 'run'])
except getopt.GetoptError, err:
print str(err)
print self._HELP_MSG
sys.exit(2)
+ self._run_on_launch = False
for o, a in opts:
if o in ('-h', '--help'):
print self._HELP_MSG
sys.exit()
if o in ('-o', '--output_png'):
- self.output_png = True
+ self._output_png = True
+ elif o in ('-r', '--run'):
+ self._run_on_launch = True
else:
assert False, _('No option action:') + ' ' + o
if args:
- self.ta_file = args[0]
+ self._ta_file = args[0]
- if len(args) > 1 or self.output_png and self.ta_file is None:
+ if len(args) > 1 or self._output_png and self._ta_file is None:
print self._HELP_MSG
sys.exit()
- if self.ta_file is not None:
- if not self.ta_file.endswith(('.ta')):
- self.ta_file += '.ta'
- if not os.path.exists(self.ta_file):
- assert False, ('%s: %s' % (self.ta_file, _('File not found')))
+ if self._ta_file is not None:
+ if not self._ta_file.endswith(('.ta')):
+ self._ta_file += '.ta'
+ if not os.path.exists(self._ta_file):
+ assert False, ('%s: %s' % (self._ta_file, _('File not found')))
def _ensure_sugar_paths(self):
''' Make sure Sugar paths are present. '''
@@ -286,8 +299,8 @@ class TurtleMain():
win.move(self.x, self.y)
win.maximize()
win.set_title(_('Turtle Art'))
- if os.path.exists(os.path.join(self._dirname, self._ICON_SUBPATH)):
- win.set_icon_from_file(os.path.join(self._dirname,
+ if os.path.exists(os.path.join(self._execdirname, self._ICON_SUBPATH)):
+ win.set_icon_from_file(os.path.join(self._execdirname,
self._ICON_SUBPATH))
win.connect('delete_event', self._quit_ta)
@@ -367,7 +380,6 @@ class TurtleMain():
MenuBuilder.make_menu_item(menu, _('Clean'), self._do_eraser_cb)
MenuBuilder.make_menu_item(menu, _('Run'), self._do_run_cb)
MenuBuilder.make_menu_item(menu, _('Step'), self._do_step_cb)
- MenuBuilder.make_menu_item(menu, _('Debug'), self._do_trace_cb)
MenuBuilder.make_menu_item(menu, _('Stop'), self._do_stop_cb)
turtle_menu = MenuBuilder.make_sub_menu(menu, _('Turtle'))
@@ -545,24 +557,26 @@ class TurtleMain():
def _do_run_cb(self, widget):
''' Callback for run button (rabbit). '''
self.tw.lc.trace = 0
- self.tw.run_button(0)
+ self.tw.hideblocks()
+ self.tw.run_button(0, running_from_button_push=True)
return
def _do_step_cb(self, widget):
''' Callback for step button (turtle). '''
self.tw.lc.trace = 0
- self.tw.run_button(3)
+ self.tw.run_button(3, running_from_button_push=True)
return
def _do_trace_cb(self, widget):
''' Callback for debug button (bug). '''
self.tw.lc.trace = 1
- self.tw.run_button(6)
+ self.tw.run_button(9, running_from_button_push=True)
return
def _do_stop_cb(self, widget):
''' Callback for stop button. '''
self.tw.lc.trace = 0
+ self.tw.showblocks()
self.tw.stop_button()
return
diff --git a/util/helpbutton.py b/util/helpbutton.py
new file mode 100644
index 0000000..47a36cd
--- /dev/null
+++ b/util/helpbutton.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (C) 2012, Gonzalo Odiard <godiard@gmail.com>
+# Copyright (C) 2012, Walter Bender <walter@sugarlabs.org>
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# HelpButton widget
+
+from gettext import gettext as _
+
+import gtk
+
+from sugar.graphics.toolbutton import ToolButton
+from sugar.graphics.icon import Icon
+from sugar.graphics import style
+
+from TurtleArt.tapalette import palette_names, help_windows
+
+import logging
+_logger = logging.getLogger('turtleart-activity')
+
+
+class HelpButton(gtk.ToolItem):
+
+ def __init__(self, activity):
+ self._activity = activity
+ self._current_palette = 'turtle'
+
+ gtk.ToolItem.__init__(self)
+
+ help_button = ToolButton('help-toolbar')
+ help_button.set_tooltip(_('Help'))
+ self.add(help_button)
+ help_button.show()
+
+ self._palette = help_button.get_palette()
+
+ help_button.connect('clicked', self.__help_button_clicked_cb)
+
+ def set_current_palette(self, name):
+ self._current_palette = name
+
+ def __help_button_clicked_cb(self, button):
+ if self._activity.palette_toolbar_button.is_expanded():
+ if not (self._current_palette in help_windows):
+ _logger.debug('name %s not found' % (self._current_palette))
+ return
+ self._palette.set_content(help_windows[self._current_palette])
+ help_windows[self._current_palette].show_all()
+ elif self._activity.edit_toolbar_button.is_expanded():
+ self._palette.set_content(help_windows['edit-toolbar'])
+ help_windows['edit-toolbar'].show_all()
+ elif self._activity.view_toolbar_button.is_expanded():
+ self._palette.set_content(help_windows['view-toolbar'])
+ help_windows['view-toolbar'].show_all()
+ elif self._activity.activity_toolbar_button.is_expanded():
+ self._palette.set_content(help_windows['activity-toolbar'])
+ help_windows['activity-toolbar'].show_all()
+ else:
+ self._palette.set_content(help_windows['main-toolbar'])
+ help_windows['main-toolbar'].show_all()
+
+ self._palette.popup(immediate=True, state=1)
+
+
+def add_section(help_box, section_text, icon=None):
+ ''' Add a section to the help palette. From helpbutton.py by
+ Gonzalo Odiard '''
+ max_text_width = int(gtk.gdk.screen_width() / 3) - 20
+ hbox = gtk.HBox()
+ label = gtk.Label()
+ label.set_use_markup(True)
+ label.set_markup('<b>%s</b>' % section_text)
+ label.set_line_wrap(True)
+ label.set_size_request(max_text_width, -1)
+ hbox.add(label)
+ if icon is not None:
+ _icon = Icon(icon_name=icon)
+ hbox.add(_icon)
+ label.set_size_request(max_text_width - 20, -1)
+ else:
+ label.set_size_request(max_text_width, -1)
+
+ hbox.show_all()
+ help_box.pack_start(hbox, False, False, padding=5)
+
+
+def add_paragraph(help_box, text, icon=None):
+ ''' Add an entry to the help palette. From helpbutton.py by
+ Gonzalo Odiard '''
+ max_text_width = int(gtk.gdk.screen_width() / 3) - 20
+ hbox = gtk.HBox()
+ label = gtk.Label(text)
+ label.set_justify(gtk.JUSTIFY_LEFT)
+ label.set_line_wrap(True)
+ hbox.add(label)
+ if icon is not None:
+ _icon = Icon(icon_name=icon)
+ hbox.add(_icon)
+ label.set_size_request(max_text_width - 20, -1)
+ else:
+ label.set_size_request(max_text_width, -1)
+
+ hbox.show_all()
+ help_box.pack_start(hbox, False, False, padding=5)