Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS28
-rw-r--r--TurtleArt/tabasics.py4
-rw-r--r--TurtleArt/tablock.py4
-rw-r--r--TurtleArt/tacollaboration.py6
-rw-r--r--TurtleArt/tagplay.py5
-rw-r--r--TurtleArt/taturtle.py31
-rw-r--r--TurtleArt/tautils.py6
-rw-r--r--TurtleArt/tawindow.py37
-rw-r--r--activity/activity.info2
-rw-r--r--plugins/turtle_blocks_extras/turtle_blocks_extras.py8
-rw-r--r--samples/graphics-bouquet.tb110
-rw-r--r--samples/graphics-floor-tiles.tb157
-rw-r--r--samples/graphics-mum.tb126
-rw-r--r--samples/thumbnails/graphics-bouquet.pngbin0 -> 32354 bytes
-rw-r--r--samples/thumbnails/graphics-floor-tiles.pngbin0 -> 4408 bytes
-rw-r--r--samples/thumbnails/graphics-mum.pngbin0 -> 48723 bytes
-rwxr-xr-xturtleblocks.py4
17 files changed, 479 insertions, 49 deletions
diff --git a/NEWS b/NEWS
index bf3360e..853ac36 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,31 @@
+191
+
+ENHANCEMENTS:
+* New sample programs (Kyoto flowers)
+* New translations
+
+BUG FIX:
+* Fixed collaboration bug (#4631)
+
+190
+
+ENHANCEMENT:
+* Set maximum number of participants
+
+BUG FIX:
+* Fix problem with null index when action and store-in blocks are
+ missing arguments.
+
+189
+
+ENHANCEMENT:
+* New sample project
+
+BUG FIXES:
+* Fix alignment problem with GNOME version
+* Fix problem with default coordinate system
+
+
188
ENHANCEMENT:
diff --git a/TurtleArt/tabasics.py b/TurtleArt/tabasics.py
index 0346d0e..beccd2a 100644
--- a/TurtleArt/tabasics.py
+++ b/TurtleArt/tabasics.py
@@ -217,7 +217,7 @@ degrees)'))
'setxy2',
2,
lambda self, x, y: primitive_dictionary['move'](
- self.tw.turtles.get_active_turtle().set_xy, (x, y)))
+ self.tw.turtles.get_active_turtle().set_xy, x, y))
define_logo_function('tasetxy', 'to tasetxy :x :y\nsetxy :x :y\nend\n')
primitive_dictionary['set'] = self._prim_set
@@ -295,7 +295,7 @@ turtle (can be used in place of a number block)'),
'setxy',
2,
lambda self, x, y: primitive_dictionary['move'](
- self.tw.turtles.get_active_turtle().set_xy, (x, y),
+ self.tw.turtles.get_active_turtle().set_xy, x, y,
pendown=False))
define_logo_function('tasetxypenup', 'to tasetxypenup :x :y\npenup\n\
setxy :x :y\npendown\nend\n')
diff --git a/TurtleArt/tablock.py b/TurtleArt/tablock.py
index 8d8ed4a..ff392e0 100644
--- a/TurtleArt/tablock.py
+++ b/TurtleArt/tablock.py
@@ -555,7 +555,7 @@ class Block:
if self.spr is None:
return
if isinstance(self.name, unicode):
- self.name = self.name.encode('ascii', 'replace')
+ self.name = self.name.encode('utf-8')
if self.name in content_blocks:
n = len(self.values)
if n == 0:
@@ -636,7 +636,7 @@ class Block:
self.svg.set_stroke_width(STANDARD_STROKE_WIDTH)
self.svg.clear_docks()
if isinstance(self.name, unicode):
- self.name = self.name.encode('ascii', 'replace')
+ self.name = self.name.encode('utf-8')
for k in block_styles.keys():
if self.name in block_styles[k]:
if isinstance(self.block_methods[k], list):
diff --git a/TurtleArt/tacollaboration.py b/TurtleArt/tacollaboration.py
index 26a21d7..4f4406b 100644
--- a/TurtleArt/tacollaboration.py
+++ b/TurtleArt/tacollaboration.py
@@ -75,7 +75,7 @@ class Collaboration():
'f': self._move_forward,
'a': self._move_in_arc,
'r': self._rotate_turtle,
- 'x': self._setxy,
+ 'x': self._set_xy,
'W': self._draw_text,
'c': self._set_pen_color,
'g': self._set_pen_gray_level,
@@ -347,12 +347,12 @@ class Collaboration():
self._tw.turtles.set_turtle(nick)
self._tw.turtles.get_active_turtle().set_heading(h, False)
- def _setxy(self, payload):
+ def _set_xy(self, payload):
if len(payload) > 0:
[nick, [x, y]] = data_from_string(payload)
if nick != self._tw.nick:
self._tw.turtles.set_turtle(nick)
- self._tw.turtles.get_active_turtle().set_xy(x, y, False)
+ self._tw.turtles.get_active_turtle().set_xy(x, y, share=False)
def _draw_text(self, payload):
if len(payload) > 0:
diff --git a/TurtleArt/tagplay.py b/TurtleArt/tagplay.py
index 9e9f821..2fc6919 100644
--- a/TurtleArt/tagplay.py
+++ b/TurtleArt/tagplay.py
@@ -235,8 +235,9 @@ class GstPlayer(gobject.GObject):
elif t == gst.MESSAGE_STATE_CHANGED:
old, new, pen = message.parse_state_changed()
if old == gst.STATE_READY and new == gst.STATE_PAUSED:
- self.emit('stream-info',
- self.player.props.stream_info_value_array)
+ if hasattr(self.player.props, 'stream_info_value_array'):
+ self.emit('stream-info',
+ self.player.props.stream_info_value_array)
# else:
# logging.debug(message.type)
diff --git a/TurtleArt/taturtle.py b/TurtleArt/taturtle.py
index 1ed557c..5e24ce7 100644
--- a/TurtleArt/taturtle.py
+++ b/TurtleArt/taturtle.py
@@ -157,7 +157,7 @@ class Turtles:
# if it is a new turtle, start it in the center of the screen
self._active_turtle = self.get_turtle(turtle_name, True, colors)
self._active_turtle.set_heading(0.0, False)
- self._active_turtle.set_xy((0.0, 0.0), False, pendown=False)
+ self._active_turtle.set_xy(0.0, 0.0, share=False, pendown=False)
self._active_turtle.set_pen_state(True)
elif colors is not None:
self._active_turtle = self.get_turtle(turtle_name, False)
@@ -333,6 +333,15 @@ class Turtle:
return
self._heading %= 360
+ self._update_sprite_heading()
+
+ if self._turtles.turtle_window.sharing() and share:
+ event = 'r|%s' % (data_to_string([self._turtles.turtle_window.nick,
+ round_int(self._heading)]))
+ self._turtles.turtle_window.send_event(event)
+
+ def _update_sprite_heading(self):
+ ''' Update the sprite to reflect the current heading '''
i = (int(self._heading + 5) % 360) / (360 / SHAPES)
if not self._hidden and self.spr is not None:
try:
@@ -340,11 +349,6 @@ class Turtle:
except IndexError:
self.spr.set_shape(self._shapes[0])
- if self._turtles.turtle_window.sharing() and share:
- event = 'r|%s' % (data_to_string([self._turtles.turtle_window.nick,
- round_int(self._heading)]))
- self._turtles.turtle_window.send_event(event)
-
def set_color(self, color=None, share=True):
''' Set the pen color for this turtle. '''
# Special case for color blocks
@@ -489,7 +493,7 @@ class Turtle:
self.spr.set_layer(TURTLE_LAYER)
self._hidden = False
self.move_turtle_spr((self._x, self._y))
- self.set_heading(self._heading)
+ self.set_heading(self._heading, share=False)
if self.label_block is not None:
self.label_block.spr.set_layer(TURTLE_LAYER + 1)
@@ -525,6 +529,8 @@ class Turtle:
return
self._heading %= 360
+ self._update_sprite_heading()
+
if self._turtles.turtle_window.sharing() and share:
event = 'r|%s' % (data_to_string([self._turtles.turtle_window.nick,
round_int(self._heading)]))
@@ -562,16 +568,15 @@ class Turtle:
int(distance)]))
self._turtles.turtle_window.send_event(event)
- def set_xy(self, pos, share=True, pendown=True, dragging=False):
+ def set_xy(self, x, y, share=True, pendown=True, dragging=False):
old = self.get_xy()
-
try:
if dragging:
- xcor = pos[0]
- ycor = pos[1]
+ xcor = x
+ ycor = y
else:
- xcor = pos[0] * self._turtles.turtle_window.coord_scale
- ycor = pos[1] * self._turtles.turtle_window.coord_scale
+ xcor = x * self._turtles.turtle_window.coord_scale
+ ycor = y * self._turtles.turtle_window.coord_scale
except (TypeError, ValueError):
debug_output('bad value sent to %s' % (__name__),
self._turtles.turtle_window.running_sugar)
diff --git a/TurtleArt/tautils.py b/TurtleArt/tautils.py
index 07b72d9..b0aa368 100644
--- a/TurtleArt/tautils.py
+++ b/TurtleArt/tautils.py
@@ -186,7 +186,7 @@ def find_hat(data):
def _to_str(text):
''' Convert whatever to a str type '''
if isinstance(text, unicode):
- return text.encode('ascii', 'replace')
+ return text.encode('utf-8')
elif isinstance(text, str):
return text
else:
@@ -371,7 +371,7 @@ def data_from_string(text):
if isinstance(text, str):
return json_load(text.replace(']],\n', ']], '))
elif isinstance(text, unicode):
- text = text.encode('ascii', 'replace')
+ text = text.encode('utf-8')
return json_load(text.replace(']],\n', ']], '))
else:
print 'type error (%s) in data_from_string' % (type(text))
@@ -415,7 +415,7 @@ def save_picture(canvas, file_name):
cr.set_source_surface(x_surface)
cr.paint()
if isinstance(file_name, unicode):
- img_surface.write_to_png(str(file_name.encode('ascii', 'replace')))
+ img_surface.write_to_png(str(file_name.encode('utf-8')))
else:
img_surface.write_to_png(str(file_name))
diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py
index 4e55d5b..af611a3 100644
--- a/TurtleArt/tawindow.py
+++ b/TurtleArt/tawindow.py
@@ -1458,7 +1458,7 @@ class TurtleArtWindow():
self.toolbar_shapes['stopiton'].set_layer(TAB_LAYER)
self.showlabel('status',
label=_('Please hit the Stop Button \
-before making changes to your Turtle Blocks program'))
+before making changes to your program'))
self._autohide_shape = True
return True
@@ -1591,13 +1591,13 @@ before making changes to your Turtle Blocks program'))
found_the_action_block = False
bname = _('action')
if isinstance(bname, unicode):
- bname = bname.encode('ascii', 'replace')
+ bname = bname.encode('utf-8')
for sblk in similars:
cblk = sblk.connections[1]
if cblk is not None:
blabel = cblk.spr.labels[0]
if isinstance(blabel, unicode):
- blabel = blabel.encode('ascii', 'replace')
+ blabel = blabel.encode('utf-8')
if bname == blabel:
found_the_action_block = True
# If there is an action block in use, change the name
@@ -1825,7 +1825,7 @@ before making changes to your Turtle Blocks program'))
if isinstance(name, (float, int)):
return
if isinstance(name, unicode):
- name = name.encode('ascii', 'replace')
+ name = name.encode('utf-8')
for blk in self.just_blocks():
if self._action_name(blk, hat=False):
if blk.spr.labels[0] == self._saved_action_name:
@@ -1843,7 +1843,7 @@ before making changes to your Turtle Blocks program'))
if isinstance(name, (float, int)):
return
if isinstance(name, unicode):
- name = name.encode('ascii', 'replace')
+ name = name.encode('utf-8')
for blk in self.just_blocks():
if self._box_name(blk, storein=False):
if blk.spr.labels[0] == self._saved_box_name:
@@ -1861,7 +1861,7 @@ before making changes to your Turtle Blocks program'))
if isinstance(name, (float, int)):
return
if isinstance(name, unicode):
- name = name.encode('ascii', 'replace')
+ name = name.encode('utf-8')
for blk in self.just_blocks():
if self._box_name(blk, storein=True):
if blk.spr.labels[0] == self._saved_box_name:
@@ -1884,11 +1884,11 @@ before making changes to your Turtle Blocks program'))
# (3) The list of proto blocks on the palette
# (4) The list of block names
if isinstance(name, unicode):
- name = name.encode('ascii', 'replace')
+ name = name.encode('utf-8')
if isinstance(old, unicode):
- old = old.encode('ascii', 'replace')
+ old = old.encode('utf-8')
if isinstance(new, unicode):
- new = new.encode('ascii', 'replace')
+ new = new.encode('utf-8')
if old == new:
'''
@@ -3901,7 +3901,8 @@ before making changes to your Turtle Blocks program'))
''' Restore a turtle from its saved state '''
tid, name, xcor, ycor, heading, color, shade, pensize = blk
self.turtles.set_turtle(key)
- self.turtles.get_active_turtle().set_xy(xcor, ycor, pendown=False)
+ self.turtles.get_active_turtle().set_xy(xcor, ycor, share=True,
+ pendown=False)
self.turtles.get_active_turtle().set_heading(heading)
self.turtles.get_active_turtle().set_color(color)
self.turtles.get_active_turtle().set_shade(shade)
@@ -4066,7 +4067,7 @@ before making changes to your Turtle Blocks program'))
if btype == 'string' and blk.spr is not None:
value = blk.values[0]
if isinstance(value, unicode):
- value = value.encode('ascii', 'replace')
+ value = value.encode('utf-8')
blk.spr.set_label(value.replace('\n', RETURN))
elif btype == 'start': # block size is saved in start block
if value is not None:
@@ -4541,16 +4542,16 @@ before making changes to your Turtle Blocks program'))
if not self.interactive_mode:
return False
if isinstance(name, unicode):
- name = name.encode('ascii', 'replace')
+ name = name.encode('utf-8')
if isinstance(label, unicode):
- label = label.encode('ascii', 'replace')
+ label = label.encode('utf-8')
i = palette_name_to_index(palette)
for blk in self.palettes[i]:
blk_label = blk.spr.labels[0]
if isinstance(blk.name, unicode):
- blk.name = blk.name.encode('ascii', 'replace')
+ blk.name = blk.name.encode('utf-8')
if isinstance(blk_label, unicode):
- blk_label = blk_label.encode('ascii', 'replace')
+ blk_label = blk_label.encode('utf-8')
if blk.name == name and blk_label == label:
return True
# Check labels[1] too (e.g., store in block)
@@ -4567,7 +4568,7 @@ before making changes to your Turtle Blocks program'))
if isinstance(name, (float, int)):
return
if isinstance(name, unicode):
- name = name.encode('ascii', 'replace')
+ name = name.encode('utf-8')
if name == _('action'):
return
# Choose a palette for the new block.
@@ -4596,7 +4597,7 @@ before making changes to your Turtle Blocks program'))
if isinstance(name, (float, int)):
return
if isinstance(name, unicode):
- name = name.encode('ascii', 'replace')
+ name = name.encode('utf-8')
if name == _('my box'):
return
# Choose a palette for the new block.
@@ -4626,7 +4627,7 @@ before making changes to your Turtle Blocks program'))
if isinstance(name, (float, int)):
return
if isinstance(name, unicode):
- name = name.encode('ascii', 'replace')
+ name = name.encode('utf-8')
if name == _('my box'):
return
# Choose a palette for the new block.
diff --git a/activity/activity.info b/activity/activity.info
index 4e37d74..9952038 100644
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -1,6 +1,6 @@
[Activity]
name = TurtleBlocks
-activity_version = 190.1
+activity_version = 191
license = MIT
bundle_id = org.laptop.TurtleArtActivity
exec = sugar-activity TurtleArtActivity.TurtleArtActivity
diff --git a/plugins/turtle_blocks_extras/turtle_blocks_extras.py b/plugins/turtle_blocks_extras/turtle_blocks_extras.py
index 8f5a94d..b1b003f 100644
--- a/plugins/turtle_blocks_extras/turtle_blocks_extras.py
+++ b/plugins/turtle_blocks_extras/turtle_blocks_extras.py
@@ -1403,8 +1403,10 @@ Journal objects'))
def _prim_showlist(self, sarray):
""" Display list of media objects """
- x = self.tw.turtles.get_active_turtle.get_xy()[0] / self.tw.coord_scale
- y = self.tw.turtles.get_active_turtle.get_xy()[1] / self.tw.coord_scale
+ x = (self.tw.turtles.get_active_turtle().get_xy()[0] /
+ self.tw.coord_scale)
+ y = (self.tw.turtles.get_active_turtle().get_xy()[1] /
+ self.tw.coord_scale)
for s in sarray:
self.tw.turtles.get_active_turtle().set_xy(x, y, pendown=False)
self._prim_show(s)
@@ -1550,7 +1552,7 @@ Journal objects'))
self.tw.show_toolbar_palette(int(arg))
else:
if type(arg) == unicode:
- arg = arg.encode('ascii', 'replace')
+ arg = arg.encode('utf-8')
if arg in palette_names:
self.tw.show_toolbar_palette(palette_name_to_index(arg))
else:
diff --git a/samples/graphics-bouquet.tb b/samples/graphics-bouquet.tb
new file mode 100644
index 0000000..028e370
--- /dev/null
+++ b/samples/graphics-bouquet.tb
@@ -0,0 +1,110 @@
+[[0, ["start", 2.0], 520, 180, [null, 99]],
+[1, ["arc", 0], 998, 402, [6, 2, 3, 4]],
+[2, ["number", 120.0], 1056, 402, [1, null]],
+[3, ["number", 30.0], 1056, 444, [1, null]],
+[4, "left", 998, 486, [1, 5, null]],
+[5, ["number", 90.0], 1056, 486, [4, null]],
+[6, ["repeat", 42], 980, 360, [27, 7, 1, 29]],
+[7, ["number", 12.0], 1039, 360, [6, null]],
+[8, "setcolor", 980, 276, [10, 9, 27]],
+[9, "white", 1057, 276, [8, null]],
+[10, "setpensize", 980, 234, [12, 11, 8]],
+[11, ["number", 20.0], 1082, 234, [10, null]],
+[12, "hat", 980, 180, [null, 13, 10]],
+[13, ["string", "stroke"], 1038, 192, [12, null]],
+[14, "setcolor", 980, 696, [22, 16, 15]],
+[15, "setgray", 980, 738, [14, 103, 106]],
+[16, "red", 1057, 696, [14, null]],
+[17, "stack", 760, 276, [67, 18, 71]],
+[18, ["string", "stroke"], 818, 276, [17, null]],
+[19, ["arc", 0], 980, 906, [24, 20, 21, 25]],
+[20, ["number", 360.0], 1038, 906, [19, null]],
+[21, ["number", 100.0], 1038, 948, [19, null]],
+[22, "setpensize", 980, 654, [65, 23, 14]],
+[23, ["number", 5], 1082, 654, [22, null]],
+[24, "startfill", 980, 864, [26, 19]],
+[25, "stopfill", 980, 990, [19, null]],
+[26, "setshade", 980, 822, [106, 107, 24]],
+[27, "left", 980, 318, [8, 28, 6]],
+[28, ["number", 45.0], 1038, 318, [27, null]],
+[29, "right", 980, 546, [6, 30, null]],
+[30, ["number", 45.0], 1038, 546, [29, null]],
+[31, "penup", 760, 434, [69, 37]],
+[32, "pendown", 760, 560, [39, 33]],
+[33, "forward", 760, 602, [32, 34, 45]],
+[34, ["number", 1.0], 831, 602, [33, null]],
+[35, "hat", 760, 180, [null, 36, 67]],
+[36, ["string", "flower"], 818, 192, [35, null]],
+[37, "right", 760, 476, [31, 38, 39]],
+[38, ["number", 90], 818, 476, [37, null]],
+[39, "forward", 760, 518, [37, 40, 32]],
+[40, ["number", 100], 831, 518, [39, null]],
+[41, "back", 760, 686, [45, 42, 43]],
+[42, ["number", 100], 818, 686, [41, null]],
+[43, "left", 760, 728, [41, 44, 46]],
+[44, ["number", 90], 818, 728, [43, null]],
+[45, "penup", 760, 644, [33, 41]],
+[46, "pendown", 760, 770, [43, null]],
+[47, ["repeat", 168], 100, 234, [79, 85, 48, null]],
+[48, "seth", 118, 276, [47, 49, 52]],
+[49, ["random", 0], 176, 276, [48, 50, 51, null]],
+[50, ["number", 0], 262, 276, [49, null]],
+[51, ["number", 360], 262, 318, [49, null]],
+[52, "penup", 118, 318, [48, 53]],
+[53, "forward", 118, 360, [52, 54, 55]],
+[54, ["random", 0], 189, 360, [53, 83, 89, null]],
+[55, "pendown", 118, 402, [53, 56]],
+[56, "stack", 118, 444, [55, 57, 58]],
+[57, ["string", "flower"], 176, 444, [56, null]],
+[58, "penup", 118, 486, [56, 59]],
+[59, ["setxy2", 0], 118, 528, [58, 60, 61, 62]],
+[60, ["number", 0], 176, 528, [59, null]],
+[61, ["number", 0], 176, 570, [59, null]],
+[62, "pendown", 118, 612, [59, null]],
+[63, "stack", 520, 772, [97, 64, null]],
+[64, ["string", "flower"], 578, 772, [63, null]],
+[65, "hat", 980, 600, [null, 66, 22]],
+[66, ["string", "fill"], 1038, 612, [65, null]],
+[67, "stack", 760, 234, [35, 68, 17]],
+[68, ["string", "fill"], 818, 234, [67, null]],
+[69, "hat", 760, 380, [null, 70, 31]],
+[70, ["string", "center"], 818, 392, [69, null]],
+[71, "stack", 760, 318, [17, 72, null]],
+[72, ["string", "center"], 818, 318, [71, null]],
+[73, ["storein", 0], 520, 352, [99, 74, 75, 76]],
+[74, ["string", "radius"], 588, 352, [73, null]],
+[75, ["number", 200.0], 588, 394, [73, null]],
+[76, ["storein", 0], 520, 436, [73, 77, 78, 81]],
+[77, ["string", "count"], 588, 436, [76, null]],
+[78, ["number", 24.0], 588, 478, [76, null]],
+[79, "hat", 100, 180, [null, 80, 47]],
+[80, ["string", "boquet"], 158, 192, [79, null]],
+[81, "stack", 520, 520, [76, 82, 91]],
+[82, ["string", "boquet"], 578, 520, [81, null]],
+[83, "box", 275, 360, [54, 84, null]],
+[84, ["string", "radius"], 330, 360, [83, null]],
+[85, "box", 159, 234, [47, 86, null]],
+[86, ["string", "count"], 214, 234, [85, null]],
+[87, "box", 329, 402, [89, 88, null]],
+[88, ["string", "radius"], 384, 402, [87, null]],
+[89, ["plus2", 0], 275, 402, [54, 87, 90]],
+[90, ["number", 100], 329, 444, [89, null]],
+[91, ["storein", 0], 520, 562, [81, 92, 93, 94]],
+[92, ["string", "radius"], 588, 562, [91, null]],
+[93, ["number", 60.0], 588, 604, [91, null]],
+[94, ["storein", 0], 520, 646, [91, 95, 96, 97]],
+[95, ["string", "count"], 588, 646, [94, null]],
+[96, ["number", 6.0], 588, 688, [94, null]],
+[97, "stack", 520, 730, [94, 98, 63]],
+[98, ["string", "boquet"], 578, 730, [97, null]],
+[99, "fillscreen2", 520, 226, [0, 100, 101, 102, 73]],
+[100, ["number", 60], 602, 226, [99, null]],
+[101, ["number", 40.0], 602, 268, [99, null]],
+[102, ["number", 0.0], 602, 310, [99, null]],
+[103, ["random", 0], 1053, 738, [15, 104, 105, null]],
+[104, ["number", 80.0], 1139, 738, [103, null]],
+[105, ["number", 100], 1139, 780, [103, null]],
+[106, ["vspace", 0], 980, 780, [15, 26]],
+[107, ["random", 0], 1065, 822, [26, 108, 109, null]],
+[108, ["number", 65.0], 1151, 822, [107, null]],
+[109, ["number", 85.0], 1151, 864, [107, null]]]
diff --git a/samples/graphics-floor-tiles.tb b/samples/graphics-floor-tiles.tb
new file mode 100644
index 0000000..0dac5dc
--- /dev/null
+++ b/samples/graphics-floor-tiles.tb
@@ -0,0 +1,157 @@
+[[0, ["start", 2.0], 640, 200, [null, 94]],
+[1, "forward", 921, 348, [16, 29, 15]],
+[2, "right", 921, 432, [15, 3, 4]],
+[3, ["number", 90], 979, 432, [2, null]],
+[4, "forward", 921, 474, [2, 13, 6]],
+[5, ["number", 3], 1046, 390, [29, null]],
+[6, "right", 921, 516, [4, 7, null]],
+[7, ["number", 90], 979, 516, [6, null]],
+[8, ["storein", 0], 640, 372, [77, 9, 10, 143]],
+[9, ["string", "size"], 708, 372, [8, null]],
+[10, ["number", 30], 708, 414, [8, null]],
+[11, "box", 1046, 348, [29, 12, null]],
+[12, ["string", "size"], 1101, 348, [11, null]],
+[13, "box", 992, 474, [4, 14, null]],
+[14, ["string", "size"], 1047, 474, [13, null]],
+[15, ["vspace", 0], 921, 390, [1, 2]],
+[16, ["repeat", 84], 903, 306, [18, 17, 1, 19]],
+[17, ["number", 2], 962, 306, [16, null]],
+[18, "startfill", 903, 264, [144, 16]],
+[19, "stopfill", 903, 576, [16, null]],
+[20, "hat", 920, 200, [null, 21, 144]],
+[21, ["string", "slat"], 978, 212, [20, null]],
+[22, "stack", 956, 514, [155, 23, 35]],
+[23, ["string", "slat"], 1014, 514, [22, null]],
+[24, ["repeat", 168], 938, 388, [145, 25, 76, null]],
+[25, ["number", 4], 997, 388, [24, null]],
+[26, "right", 956, 682, [38, 27, 32]],
+[27, ["number", 90], 1014, 682, [26, null]],
+[28, "forward", 956, 598, [35, 43, 38]],
+[29, ["product2", 0], 992, 348, [1, 11, 5]],
+[30, "box", 1081, 598, [43, 31, null]],
+[31, ["string", "size"], 1136, 598, [30, null]],
+[32, "forward", 956, 724, [26, 33, 36]],
+[33, "box", 1027, 724, [32, 34, null]],
+[34, ["string", "size"], 1082, 724, [33, null]],
+[35, "penup", 956, 556, [22, 28]],
+[36, "pendown", 956, 766, [32, null]],
+[37, ["number", 2], 1081, 640, [43, null]],
+[38, ["vspace", 0], 956, 640, [28, 26]],
+[39, "hat", 920, 300, [null, 40, 145]],
+[40, ["string", "slats_1"], 978, 312, [39, null]],
+[41, "stack", 380, 380, [99, 42, 101]],
+[42, ["string", "slats_1"], 438, 380, [41, null]],
+[43, ["product2", 0], 1027, 598, [28, 30, 37]],
+[44, "left", 123, 306, [46, 45, 50]],
+[45, ["number", 90], 181, 306, [44, null]],
+[46, "penup", 123, 264, [148, 44]],
+[47, "pendown", 123, 432, [48, null]],
+[48, "right", 123, 390, [50, 49, 47]],
+[49, ["number", 90], 181, 390, [48, null]],
+[50, "forward", 123, 348, [44, 51, 48]],
+[51, "box", 194, 348, [50, 52, null]],
+[52, ["string", "size"], 249, 348, [51, null]],
+[53, "hat", 920, 400, [null, 54, 146]],
+[54, ["string", "slats_2"], 978, 412, [53, null]],
+[55, ["repeat", 168], 938, 488, [146, 56, 142, null]],
+[56, ["number", 4], 997, 488, [55, null]],
+[57, "stack", 956, 614, [156, 58, 59]],
+[58, ["string", "slat"], 1014, 614, [57, null]],
+[59, "penup", 956, 656, [57, 60]],
+[60, "forward", 956, 698, [59, 61, 65]],
+[61, ["product2", 0], 1027, 698, [60, 62, 64]],
+[62, "box", 1081, 698, [61, 63, null]],
+[63, ["string", "size"], 1136, 698, [62, null]],
+[64, ["number", 3], 1081, 740, [61, null]],
+[65, ["vspace", 0], 956, 740, [60, 66]],
+[66, "right", 956, 782, [65, 67, 68]],
+[67, ["number", 90], 1014, 782, [66, null]],
+[68, "forward", 956, 824, [66, 72, 71]],
+[69, "box", 1081, 824, [72, 70, null]],
+[70, ["string", "size"], 1136, 824, [69, null]],
+[71, "pendown", 956, 866, [68, null]],
+[72, ["product2", 0], 1027, 824, [68, 69, 73]],
+[73, ["number", 2], 1081, 866, [72, null]],
+[74, "stack", 380, 464, [101, 75, null]],
+[75, ["string", "slats_2"], 438, 464, [74, null]],
+[76, "setgray", 956, 430, [24, 152, 155]],
+[77, "setshade", 640, 330, [112, 78, 8]],
+[78, ["number", 40], 725, 330, [77, null]],
+[79, "setshade", 660, 1102, [96, 82, null]],
+[80, "shade", 842, 1144, [82, null]],
+[81, ["number", 100], 818, 1102, [82, null]],
+[82, ["minus2", 0], 745, 1102, [79, 81, 80]],
+[83, ["repeat", 21], 660, 916, [95, 84, 85, 96]],
+[84, ["number", 4], 719, 916, [83, null]],
+[85, "forward", 678, 958, [83, 88, 86]],
+[86, "right", 678, 1000, [85, 87, null]],
+[87, ["number", 90], 736, 1000, [86, null]],
+[88, "box", 749, 958, [85, 89, null]],
+[89, ["string", "size"], 804, 958, [88, null]],
+[90, "hat", 660, 820, [null, 91, 95]],
+[91, ["string", "center"], 718, 832, [90, null]],
+[92, "stack", 380, 296, [135, 93, 99]],
+[93, ["string", "center"], 438, 296, [92, null]],
+[94, "clean", 640, 246, [0, 112]],
+[95, "startfill", 660, 874, [90, 83]],
+[96, "stopfill", 660, 1060, [83, 79]],
+[97, "hat", 140, 200, [null, 98, 148]],
+[98, ["string", "jog"], 198, 212, [97, null]],
+[99, "stack", 380, 338, [92, 100, 41]],
+[100, ["string", "jog"], 438, 338, [99, null]],
+[101, "stack", 380, 422, [41, 102, 74]],
+[102, ["string", "jog"], 438, 422, [101, null]],
+[103, ["repeat", 0], 659, 760, [118, 104, 105, null]],
+[104, ["number", 3], 718, 760, [103, null]],
+[105, "stack", 677, 802, [103, 106, null]],
+[106, ["string", "jog"], 735, 802, [105, null]],
+[107, "penup", 623, 466, [143, 109]],
+[108, "pendown", 623, 592, [109, 121]],
+[109, ["setxy2", 0], 623, 508, [107, 110, 111, 108]],
+[110, "rightpos", 681, 508, [109, null]],
+[111, "toppos", 681, 550, [109, null]],
+[112, "setpensize", 640, 288, [94, 113, 77]],
+[113, ["number", 1], 742, 288, [112, null]],
+[114, "hat", 380, 200, [null, 115, 135]],
+[115, ["string", "tile"], 438, 212, [114, null]],
+[116, "setcolor", 123, 406, [140, 137, null]],
+[117, ["repeat", 51], 641, 676, [121, 120, 118, 122]],
+[118, "stack", 659, 718, [117, 119, 103]],
+[119, ["string", "tile"], 717, 718, [118, null]],
+[120, ["number", 13], 700, 676, [117, null]],
+[121, ["repeat", 165], 623, 634, [108, 132, 117, null]],
+[122, "penup", 641, 880, [117, 123]],
+[123, ["setxy2", 0], 641, 922, [122, 125, 126, 131]],
+[124, "ycor", 772, 964, [126, null]],
+[125, "rightpos", 699, 922, [123, null]],
+[126, ["minus2", 0], 699, 964, [123, 124, 127]],
+[127, ["product2", 0], 796, 1006, [126, 129, 128]],
+[128, ["number", 5], 850, 1048, [127, null]],
+[129, "box", 850, 1006, [127, 130, null]],
+[130, ["string", "size"], 905, 1006, [129, null]],
+[131, "pendown", 641, 1006, [123, null]],
+[132, ["number", 7], 682, 634, [121, null]],
+[133, "hat", 140, 300, [null, 134, 147]],
+[134, ["string", "random color"], 198, 312, [133, null]],
+[135, "stack", 380, 254, [114, 136, 92]],
+[136, ["string", "random color"], 438, 254, [135, null]],
+[137, ["random", 0], 200, 406, [116, 138, 139, null]],
+[138, ["number", 0], 286, 406, [137, null]],
+[139, ["number", 100], 286, 448, [137, null]],
+[140, "setgray", 123, 364, [147, 141, 116]],
+[141, ["number", 100], 196, 364, [140, null]],
+[142, "setgray", 956, 530, [55, 149, 156]],
+[143, "sandwichclampcollapsed", 640, 456, [8, 107, null]],
+[144, "sandwichclampcollapsed", 920, 254, [20, 18, null]],
+[145, "sandwichclampcollapsed", 920, 354, [39, 24, null]],
+[146, "sandwichclampcollapsed", 920, 454, [53, 55, null]],
+[147, "sandwichclampcollapsed", 140, 354, [133, 140, null]],
+[148, "sandwichclampcollapsed", 140, 254, [97, 46, null]],
+[149, ["random", 0], 1029, 530, [142, 150, 151, null]],
+[150, ["number", 50.0], 1115, 530, [149, null]],
+[151, ["number", 100], 1115, 572, [149, null]],
+[152, ["random", 0], 1029, 430, [76, 153, 154, null]],
+[153, ["number", 75.0], 1115, 430, [152, null]],
+[154, ["number", 100], 1115, 472, [152, null]],
+[155, ["vspace", 0], 956, 472, [76, 22]],
+[156, ["vspace", 0], 956, 572, [142, 57]]]
diff --git a/samples/graphics-mum.tb b/samples/graphics-mum.tb
new file mode 100644
index 0000000..241787e
--- /dev/null
+++ b/samples/graphics-mum.tb
@@ -0,0 +1,126 @@
+[[0, ["start", 2.0], 1140, 80, [null, 51]],
+[1, ["arc", 0], 618, 600, [11, 2, 3, 15]],
+[2, ["number", 15.0], 676, 600, [1, null]],
+[3, ["number", 100], 676, 642, [1, null]],
+[4, "left", 600, 516, [48, 5, 11]],
+[5, ["number", 60.0], 658, 516, [4, null]],
+[6, "right", 600, 870, [11, 7, 8]],
+[7, ["number", 60.0], 658, 870, [6, null]],
+[8, ["arc", 0], 600, 912, [6, 9, 10, 13]],
+[9, ["number", 120.0], 658, 912, [8, null]],
+[10, ["number", 100], 658, 954, [8, null]],
+[11, ["repeat", 105], 600, 558, [4, 12, 1, 6]],
+[12, ["number", 8.0], 659, 558, [11, null]],
+[13, "right", 600, 996, [8, 14, null]],
+[14, ["number", 120.0], 658, 996, [13, null]],
+[15, "right", 618, 684, [1, 16, 17]],
+[16, ["number", 90], 676, 684, [15, null]],
+[17, "forward", 618, 726, [15, 18, 21]],
+[18, ["number", 20.0], 689, 726, [17, null]],
+[19, "left", 618, 810, [21, 20, null]],
+[20, ["number", 90], 676, 810, [19, null]],
+[21, "back", 618, 768, [17, 22, 19]],
+[22, ["number", 20.0], 676, 768, [21, null]],
+[23, ["arc", 0], 360, 600, [35, 24, 25, 36]],
+[24, ["number", 120.0], 418, 600, [23, null]],
+[25, ["number", 100], 418, 642, [23, null]],
+[26, "left", 360, 516, [47, 27, 35]],
+[27, ["number", 60.0], 418, 516, [26, null]],
+[28, "right", 360, 726, [36, 29, 37]],
+[29, ["number", 60.0], 418, 726, [28, null]],
+[30, ["arc", 0], 360, 810, [37, 31, 32, 38]],
+[31, ["number", 120.0], 418, 810, [30, null]],
+[32, ["number", 100], 418, 852, [30, null]],
+[33, "right", 360, 936, [38, 34, null]],
+[34, ["number", 120.0], 418, 936, [33, null]],
+[35, "startfill", 360, 558, [26, 23]],
+[36, "stopfill", 360, 684, [23, 28]],
+[37, "startfill", 360, 768, [28, 30]],
+[38, "stopfill", 360, 894, [30, 33]],
+[39, "hat", 360, 420, [null, 40, 47]],
+[40, ["string", "action"], 418, 432, [39, null]],
+[41, "hat", 600, 420, [null, 42, 48]],
+[42, ["string", "action_1"], 658, 432, [41, null]],
+[43, "stack", 120, 484, [54, 44, 45]],
+[44, ["string", "action"], 178, 484, [43, null]],
+[45, "stack", 120, 526, [43, 46, 59]],
+[46, ["string", "action_1"], 178, 526, [45, null]],
+[47, "setcolor", 360, 474, [39, 50, 26]],
+[48, "setcolor", 600, 474, [41, 49, 4]],
+[49, "red", 677, 474, [48, null]],
+[50, "white", 437, 474, [47, null]],
+[51, "setpensize", 1140, 126, [0, 52, 89]],
+[52, ["number", 10.0], 1242, 126, [51, null]],
+[53, "penup", 120, 274, [69, 61]],
+[54, "pendown", 120, 442, [55, 43]],
+[55, "left", 120, 400, [63, 56, 54]],
+[56, ["number", 180.0], 178, 400, [55, null]],
+[57, "right", 120, 610, [59, 58, 67]],
+[58, ["number", 180.0], 178, 610, [57, null]],
+[59, "penup", 120, 568, [45, 57]],
+[60, "pendown", 120, 736, [65, null]],
+[61, "left", 120, 316, [53, 62, 63]],
+[62, ["number", 90], 178, 316, [61, null]],
+[63, "forward", 120, 358, [61, 64, 55]],
+[64, ["number", 85.0], 191, 358, [63, null]],
+[65, "right", 120, 694, [67, 66, 60]],
+[66, ["number", 90], 178, 694, [65, null]],
+[67, "back", 120, 652, [57, 68, 65]],
+[68, ["number", 85.0], 178, 652, [67, null]],
+[69, "hat", 120, 220, [null, 70, 53]],
+[70, ["string", "petal"], 178, 232, [69, null]],
+[71, ["repeat", 189], 840, 154, [106, 101, 72, null]],
+[72, "seth", 858, 196, [71, 73, 76]],
+[73, ["random", 0], 916, 196, [72, 74, 75, null]],
+[74, ["number", 0], 1002, 196, [73, null]],
+[75, ["number", 360.0], 1002, 238, [73, null]],
+[76, ["vspace", 0], 858, 238, [72, 81]],
+[77, "forward", 858, 322, [81, 87, 82]],
+[78, ["setxy2", 0], 858, 490, [83, 79, 80, 84]],
+[79, ["number", 0], 916, 490, [78, null]],
+[80, ["number", 0], 916, 532, [78, null]],
+[81, "penup", 858, 280, [76, 77]],
+[82, "pendown", 858, 364, [77, 85]],
+[83, "penup", 858, 448, [85, 78]],
+[84, "pendown", 858, 574, [78, null]],
+[85, "stack", 858, 406, [82, 86, 83]],
+[86, ["string", "petal"], 916, 406, [85, null]],
+[87, ["random", 0], 929, 322, [77, 99, 105, null]],
+[88, ["number", 50.0], 1069, 364, [105, null]],
+[89, "fillscreen2", 1140, 168, [51, 90, 91, 92, 93]],
+[90, ["number", 60], 1222, 168, [89, null]],
+[91, ["number", 80], 1222, 210, [89, null]],
+[92, ["number", 100], 1222, 252, [89, null]],
+[93, ["storein", 0], 1140, 294, [89, 94, 95, 96]],
+[94, ["string", "count"], 1208, 294, [93, null]],
+[95, ["number", 36.0], 1208, 336, [93, null]],
+[96, ["storein", 0], 1140, 378, [93, 97, 98, 110]],
+[97, ["string", "radius"], 1208, 378, [96, null]],
+[98, ["number", 250.0], 1208, 420, [96, null]],
+[99, "box", 1015, 322, [87, 100, null]],
+[100, ["string", "radius"], 1070, 322, [99, null]],
+[101, "box", 899, 154, [71, 102, null]],
+[102, ["string", "count"], 954, 154, [101, null]],
+[103, "box", 1069, 406, [105, 104, null]],
+[104, ["string", "radius"], 1124, 406, [103, null]],
+[105, ["plus2", 0], 1015, 364, [87, 88, 103]],
+[106, "hat", 840, 100, [null, 107, 71]],
+[107, ["string", "action_2"], 898, 112, [106, null]],
+[108, "stack", 1158, 504, [110, 109, 112]],
+[109, ["string", "action_2"], 1216, 504, [108, null]],
+[110, ["repeat", 105], 1140, 462, [96, 111, 108, null]],
+[111, ["number", 5.0], 1199, 462, [110, null]],
+[112, ["storein", 0], 1158, 546, [108, 113, 118, 124]],
+[113, ["string", "radius"], 1226, 546, [112, null]],
+[114, ["storein", 0], 1158, 672, [124, 115, 117, null]],
+[115, ["string", "count"], 1226, 672, [114, null]],
+[116, ["number", 4.0], 1323, 756, [117, null]],
+[117, ["minus2", 0], 1226, 714, [114, 121, 116]],
+[118, ["division2", 0], 1226, 588, [112, 119, 123]],
+[119, "box", 1296, 588, [118, 120, null]],
+[120, ["string", "radius"], 1351, 588, [119, null]],
+[121, "box", 1299, 714, [117, 122, null]],
+[122, ["string", "count"], 1354, 714, [121, null]],
+[123, ["number", 1.5], 1320, 630, [118, null]],
+[124, ["vspace", 0], 1158, 630, [112, 114]],
+[-1, ["turtle", "Yertle"], 0.0, 0.0, 320.0, 0, 50, 10.0]] \ No newline at end of file
diff --git a/samples/thumbnails/graphics-bouquet.png b/samples/thumbnails/graphics-bouquet.png
new file mode 100644
index 0000000..1299df5
--- /dev/null
+++ b/samples/thumbnails/graphics-bouquet.png
Binary files differ
diff --git a/samples/thumbnails/graphics-floor-tiles.png b/samples/thumbnails/graphics-floor-tiles.png
new file mode 100644
index 0000000..147dd82
--- /dev/null
+++ b/samples/thumbnails/graphics-floor-tiles.png
Binary files differ
diff --git a/samples/thumbnails/graphics-mum.png b/samples/thumbnails/graphics-mum.png
new file mode 100644
index 0000000..c5ec53f
--- /dev/null
+++ b/samples/thumbnails/graphics-mum.png
Binary files differ
diff --git a/turtleblocks.py b/turtleblocks.py
index 7c85c97..24b6343 100755
--- a/turtleblocks.py
+++ b/turtleblocks.py
@@ -552,7 +552,7 @@ Would you like to save before quitting?'))
filename, self.tw.load_save_folder = get_save_name(
save_type, self.tw.load_save_folder, 'logosession')
if isinstance(filename, unicode):
- filename = filename.encode('ascii', 'replace')
+ filename = filename.encode('utf-8')
if filename is not None:
f = file(filename, 'w')
f.write(logocode)
@@ -579,7 +579,7 @@ Would you like to save before quitting?'))
if self._setting_gconf_overrides:
return
if self.tw.coord_scale == 1:
- self.tw.coord_scale = int(self.tw.height / 40.)
+ self.tw.coord_scale = self.tw.height / 40
self.tw.update_overlay_position()
if self.tw.cartesian is True:
self.tw.overlay_shapes['Cartesian_labeled'].hide()