Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarion <marion.zepf@gmail.com>2013-08-31 17:05:51 (GMT)
committer Marion <marion.zepf@gmail.com>2013-08-31 17:05:51 (GMT)
commitb824b27903c7fb01e1880551a0d8ed1eea187bf4 (patch)
tree536bdea70f059c9aa6c767a496cc5075eefa420c
parent8076e1880999823d3c5df393431a419b3f9780c2 (diff)
parente108487cff19177002f60f1d754f9a205fb91d15 (diff)
update Primitive of 'setxy' block; Merge mainline/master into type-system
Conflicts: TurtleArt/tabasics.py -- replace Primitive for 'setxy' block with a completely new one (i.e. reject both versions) - Also add a Primitive for the deprecated version of the 'setxy' block.
-rw-r--r--NEWS15
-rw-r--r--TurtleArt/tabasics.py22
-rw-r--r--TurtleArt/taprimitive.py2
-rw-r--r--TurtleArt/taturtle.py13
-rw-r--r--TurtleArt/tawindow.py6
-rw-r--r--TurtleArtActivity.py2
-rw-r--r--activity/activity.info2
-rw-r--r--plugins/turtle_blocks_extras/turtle_blocks_extras.py6
-rw-r--r--po/ko.po67
-rw-r--r--pysamples/dotted_line.py4
-rw-r--r--samples/graphics-grid.tb161
-rw-r--r--samples/thumbnails/graphics-grid.pngbin0 -> 15989 bytes
12 files changed, 237 insertions, 63 deletions
diff --git a/NEWS b/NEWS
index bf3360e..450d30c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,18 @@
+190
+
+ENHANCEMENT:
+* Set maximum number of participants
+
+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 b943e35..8bb50e4 100644
--- a/TurtleArt/tabasics.py
+++ b/TurtleArt/tabasics.py
@@ -267,14 +267,9 @@ degrees)'))
default=[0, 0],
help_string=_('moves turtle to position xcor, ycor; \
(0, 0) is in the center of the screen.'))
- self.tw.lc.def_prim(
- 'setxy2',
- 2,
+ self.tw.lc.def_prim('setxy2', 2,
Primitive(Turtle.set_xy,
- slot_wrappers={(0, 2): Primitive(Primitive.make_tuple,
- slot_wrappers={0:self.prim_cache["convert_value_for_move"],
- 1:self.prim_cache["convert_value_for_move"]
- })},
+ arg_descs=[ArgSlot(TYPE_NUMBER), ArgSlot(TYPE_NUMBER)],
call_afterwards=self.after_move))
define_logo_function('tasetxy', 'to tasetxy :x :y\nsetxy :x :y\nend\n')
@@ -345,12 +340,11 @@ turtle (can be used in place of a number block)'),
logo_command='tasetxypenup',
help_string=_('moves turtle to position xcor, ycor; \
(0, 0) is in the center of the screen.'))
- self.tw.lc.def_prim(
- 'setxy',
- 2,
- lambda self, x, y: primitive_dictionary['move'](
- self.tw.turtles.get_active_turtle().set_xy, (x, y),
- pendown=False))
+ self.tw.lc.def_prim('setxy', 2,
+ Primitive(Turtle.set_xy,
+ arg_descs=[ArgSlot(TYPE_NUMBER), ArgSlot(TYPE_NUMBER)],
+ kwarg_descs={'pendown': ConstantArg(False)},
+ call_afterwards=self.after_move))
define_logo_function('tasetxypenup', 'to tasetxypenup :x :y\npenup\n\
setxy :x :y\npendown\nend\n')
@@ -1237,7 +1231,7 @@ variable'))
self.after_move()
- def after_move(self, *ignored_args):
+ def after_move(self, *ignored_args, **ignored_kwargs):
''' Update labels after moving the turtle '''
if self.tw.lc.update_values:
self.tw.lc.update_label_value(
diff --git a/TurtleArt/taprimitive.py b/TurtleArt/taprimitive.py
index d664080..e09963b 100644
--- a/TurtleArt/taprimitive.py
+++ b/TurtleArt/taprimitive.py
@@ -58,7 +58,7 @@ class Primitive(object):
but that can also be transformed into a Python AST.
"""
- _DEBUG = False
+ _DEBUG = True
STANDARD_OPERATORS = {'plus': (ast.UAdd, ast.Add),
'minus': (ast.USub, ast.Sub),
diff --git a/TurtleArt/taturtle.py b/TurtleArt/taturtle.py
index 5359c65..d145f0b 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, False, pendown=False)
self._active_turtle.set_pen_state(True)
elif colors is not None:
self._active_turtle = self.get_turtle(turtle_name, False)
@@ -537,16 +537,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/tawindow.py b/TurtleArt/tawindow.py
index 45e72ee..52cf2c4 100644
--- a/TurtleArt/tawindow.py
+++ b/TurtleArt/tawindow.py
@@ -2568,10 +2568,12 @@ before making changes to your Turtle Blocks program'))
pos = self.turtles.screen_to_turtle_coordinates((dx, dy))
if self.selected_turtle.get_pen_state():
self.selected_turtle.set_pen_state(False)
- self.selected_turtle.set_xy(pos, share=False, dragging=True)
+ self.selected_turtle.set_xy(*pos, share=False,
+ dragging=True)
self.selected_turtle.set_pen_state(True)
else:
- self.selected_turtle.set_xy(pos, share=False, dragging=True)
+ self.selected_turtle.set_xy(*pos, share=False,
+ dragging=True)
if self.update_counter % 5:
self.lc.update_label_value(
'xcor', self.selected_turtle.get_xy()[0] /
diff --git a/TurtleArtActivity.py b/TurtleArtActivity.py
index b45b12f..078377b 100644
--- a/TurtleArtActivity.py
+++ b/TurtleArtActivity.py
@@ -614,6 +614,8 @@ class TurtleArtActivity(activity.Activity):
def _setup_toolbar(self):
''' Setup toolbar according to Sugar version. '''
if self.has_toolbarbox:
+ self.max_participants = 4
+
self._setup_toolbar_help()
self._toolbox = ToolbarBox()
diff --git a/activity/activity.info b/activity/activity.info
index d13a4ac..f0fcf70 100644
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -1,6 +1,6 @@
[Activity]
name = TurtleBlocks
-activity_version = 188
+activity_version = 190
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 d3865c7..ce18907 100644
--- a/plugins/turtle_blocks_extras/turtle_blocks_extras.py
+++ b/plugins/turtle_blocks_extras/turtle_blocks_extras.py
@@ -1414,8 +1414,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)
diff --git a/po/ko.po b/po/ko.po
index 8eeab45..cc5a5c6 100644
--- a/po/ko.po
+++ b/po/ko.po
@@ -7,15 +7,14 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-05-17 00:31-0400\n"
-"PO-Revision-Date: 2009-05-10 23:43-0400\n"
+"PO-Revision-Date: 2013-08-06 11:21+0900\n"
"Last-Translator: Donghee Park <i4u_4ever@yahoo.com>\n"
"Language-Team: LANGUAGE <walter@sugarlabs.org>\n"
-"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Pootle 1.2.1\n"
+"X-Generator: Poedit 1.5.7\n"
#. TRANS: "name" option from activity.info file
msgid "TurtleBlocks"
@@ -86,7 +85,7 @@ msgstr "도"
#: TurtleArt/tabasics.py:182
msgid "radius"
-msgstr "라디우스"
+msgstr "반지름"
#: TurtleArt/tabasics.py:186
msgid "moves turtle along an arc"
@@ -177,7 +176,7 @@ msgstr ""
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:1194
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:1199
msgid "gray"
-msgstr ""
+msgstr "회색"
#: TurtleArt/tabasics.py:309
msgid "set color"
@@ -197,7 +196,7 @@ msgstr ""
#: TurtleArt/tabasics.py:333
msgid "set gray"
-msgstr ""
+msgstr "회색으로 설정"
#: TurtleArt/tabasics.py:336
msgid "sets gray level of the line drawn by the turtle"
@@ -241,7 +240,7 @@ msgstr ""
#: TurtleArt/tabasics.py:404
msgid "start fill"
-msgstr ""
+msgstr "채우기 시작"
#: TurtleArt/tabasics.py:406
msgid "starts filled polygon (used with end fill block)"
@@ -249,7 +248,7 @@ msgstr ""
#: TurtleArt/tabasics.py:413
msgid "end fill"
-msgstr ""
+msgstr "채우기 끝"
#: TurtleArt/tabasics.py:415
msgid "completes filled polygon (used with start fill block)"
@@ -269,35 +268,35 @@ msgstr ""
#: TurtleArt/tabasics.py:439
msgid "red"
-msgstr ""
+msgstr "빨간색"
#: TurtleArt/tabasics.py:440
msgid "orange"
-msgstr ""
+msgstr "오렌지색"
#: TurtleArt/tabasics.py:442
msgid "yellow"
-msgstr ""
+msgstr "노란색"
#: TurtleArt/tabasics.py:444
msgid "green"
-msgstr ""
+msgstr "초록색"
#: TurtleArt/tabasics.py:445
msgid "cyan"
-msgstr ""
+msgstr "사이안색"
#: TurtleArt/tabasics.py:446
msgid "blue"
-msgstr ""
+msgstr "파란색"
#: TurtleArt/tabasics.py:447
msgid "purple"
-msgstr ""
+msgstr "보라색"
#: TurtleArt/tabasics.py:449
msgid "white"
-msgstr ""
+msgstr "하얀색"
#: TurtleArt/tabasics.py:450
#, fuzzy
@@ -497,7 +496,7 @@ msgstr "이면"
#: TurtleArt/tabasics.py:775
msgid "if then"
-msgstr ""
+msgstr "만약"
#: TurtleArt/tabasics.py:777
msgid "if-then operator that uses boolean operators from Numbers palette"
@@ -509,7 +508,7 @@ msgstr "아니면"
#: TurtleArt/tabasics.py:789 TurtleArt/tabasics.py:797
msgid "if then else"
-msgstr ""
+msgstr "그 외"
#: TurtleArt/tabasics.py:790 TurtleArt/tabasics.py:798
msgid "if-then-else operator that uses boolean operators from Numbers palette"
@@ -533,7 +532,7 @@ msgstr ""
#: TurtleArt/tabasics.py:822
msgid "stop action"
-msgstr ""
+msgstr "멈춤"
#: TurtleArt/tabasics.py:825
msgid "stops current action"
@@ -573,7 +572,7 @@ msgstr ""
#: TurtleArt/tawindow.py:1461 TurtleArt/tawindow.py:2077
#: TurtleArt/tawindow.py:4363
msgid "action"
-msgstr ""
+msgstr "행동"
#: TurtleArt/tabasics.py:861
msgid "top of nameable action stack"
@@ -617,7 +616,7 @@ msgstr ""
#: TurtleArt/tabasics.py:924 TurtleArt/tawindow.py:4427
msgid "store in"
-msgstr ""
+msgstr "담기"
#: TurtleArt/tabasics.py:924 TurtleArt/tabasics.py:939
msgid "box"
@@ -625,7 +624,7 @@ msgstr "상자"
#: TurtleArt/tabasics.py:924 TurtleArt/tawindow.py:4427
msgid "value"
-msgstr ""
+msgstr "물체"
#: TurtleArt/tabasics.py:928 TurtleArt/tabasics.py:942
#: TurtleArt/tawindow.py:1355 TurtleArt/tawindow.py:1486
@@ -1128,7 +1127,7 @@ msgstr ""
#: plugins/accelerometer/accelerometer.py:56
#: plugins/accelerometer/accelerometer.py:63
msgid "acceleration"
-msgstr ""
+msgstr "가속도"
#: plugins/accelerometer/accelerometer.py:58
#: plugins/accelerometer/accelerometer.py:65
@@ -1148,7 +1147,7 @@ msgstr ""
#: plugins/audio_sensors/audio_sensors.py:90
#: plugins/audio_sensors/audio_sensors.py:105
msgid "loudness"
-msgstr ""
+msgstr "소리크기"
#: plugins/audio_sensors/audio_sensors.py:91
#: plugins/audio_sensors/audio_sensors.py:106
@@ -1206,7 +1205,7 @@ msgstr ""
#: plugins/light_sensor/light_sensor.py:56
#: plugins/light_sensor/light_sensor.py:63
msgid "brightness"
-msgstr ""
+msgstr "밝기"
#: plugins/camera_sensor/camera_sensor.py:82
#: plugins/camera_sensor/camera_sensor.py:130
@@ -1242,7 +1241,7 @@ msgstr ""
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:109
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:112
msgid "while"
-msgstr ""
+msgstr "하는 동안"
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:113
msgid "do-while-True operator that uses boolean operators from Numbers palette"
@@ -1251,7 +1250,7 @@ msgstr ""
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:119
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:122
msgid "until"
-msgstr ""
+msgstr "할 때 까지"
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:123
msgid "do-until-True operator that uses boolean operators from Numbers palette"
@@ -1303,7 +1302,7 @@ msgstr ""
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:200
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:228
msgid "show"
-msgstr ""
+msgstr "보이기"
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:204
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:217
@@ -1417,7 +1416,7 @@ msgstr ""
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:343
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:354
msgid "button down"
-msgstr ""
+msgstr "마우스 누름"
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:346
msgid "returns 1 if mouse button is pressed"
@@ -1429,7 +1428,7 @@ msgstr ""
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:364
msgid "mouse x"
-msgstr ""
+msgstr "마우스 가로 위치"
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:367
msgid "returns mouse x coordinate"
@@ -1437,7 +1436,7 @@ msgstr ""
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:374
msgid "mouse y"
-msgstr ""
+msgstr "마우스 세로 위치"
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:377
msgid "returns mouse y coordinate"
@@ -1462,7 +1461,7 @@ msgstr ""
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:430
msgid "read pixel"
-msgstr ""
+msgstr "색 확인"
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:433
msgid "RGB color under the turtle is pushed to the stack"
@@ -1470,7 +1469,7 @@ msgstr ""
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:441
msgid "turtle sees"
-msgstr ""
+msgstr "거북이가 보는 색깔"
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:443
msgid "returns the color that the turtle \"sees\""
@@ -1478,7 +1477,7 @@ msgstr ""
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:451
msgid "time"
-msgstr ""
+msgstr "시간"
#: plugins/turtle_blocks_extras/turtle_blocks_extras.py:454
msgid "elapsed time (in seconds) since program started"
diff --git a/pysamples/dotted_line.py b/pysamples/dotted_line.py
index c581f83..c0d3008 100644
--- a/pysamples/dotted_line.py
+++ b/pysamples/dotted_line.py
@@ -94,8 +94,8 @@
# fillscreen(self, c, s)
# tw.turtles.get_active_turtle().fillscreen(70, 90)
# Note: Fill the screen with color 70, shade 90 (light blue)
-# self.set_xy(self, (x, y))
-# tw.turtles.get_active_turtle().set_xy((100,100))
+# self.set_xy(self, x, y)
+# tw.turtles.get_active_turtle().set_xy(100,100)
# Note: Move the turtle to position (100, 100)
# self.get_xy tw.turtles.get_active_turtle().get_xy()[0]
# Note: The current x coordinate of the turtle
diff --git a/samples/graphics-grid.tb b/samples/graphics-grid.tb
new file mode 100644
index 0000000..03235d8
--- /dev/null
+++ b/samples/graphics-grid.tb
@@ -0,0 +1,161 @@
+[[0, ["start", 2.0], 0, 180, [null, 32]],
+[1, ["repeat", 21], 1240, 276, [11, 2, 8, 12]],
+[2, ["number", 4], 1299, 276, [1, null]],
+[3, ["storein", 0], 640, 514, [118, 4, 5, 57]],
+[4, ["string", "side"], 708, 514, [3, null]],
+[5, ["number", 24], 708, 556, [3, null]],
+[6, "box", 1329, 318, [8, 7, null]],
+[7, ["string", "side"], 1384, 318, [6, null]],
+[8, "forward", 1258, 318, [1, 6, 9]],
+[9, "right", 1258, 360, [8, 10, null]],
+[10, ["number", 90], 1316, 360, [9, null]],
+[11, "startfill", 1240, 234, [13, 1]],
+[12, "stopfill", 1240, 420, [1, null]],
+[13, "hat", 1240, 180, [null, 14, 11]],
+[14, ["string", "square"], 1298, 192, [13, null]],
+[15, "stack", 36, 1016, [80, 16, 49]],
+[16, ["string", "square"], 94, 1016, [15, null]],
+[17, ["repeat", 105], 18, 806, [47, 27, 48, 51]],
+[18, "seth", 36, 890, [48, 19, 22]],
+[19, ["random", 0], 94, 890, [18, 20, 21, null]],
+[20, ["number", -15], 180, 890, [19, null]],
+[21, ["number", 15], 180, 932, [19, null]],
+[22, ["vspace", 0], 36, 932, [18, 80]],
+[23, ["repeat", 177], 0, 722, [132, 26, 47, null]],
+[24, "width", 147, 806, [27, null]],
+[25, "height", 129, 722, [26, null]],
+[26, ["division2", 0], 59, 722, [23, 25, 28]],
+[27, ["division2", 0], 77, 806, [17, 24, 30]],
+[28, "box", 153, 764, [26, 29, null]],
+[29, ["string", "grid spacing"], 208, 764, [28, null]],
+[30, "box", 171, 848, [27, 31, null]],
+[31, ["string", "grid spacing"], 226, 848, [30, null]],
+[32, ["storein", 0], 0, 226, [0, 33, 34, 122]],
+[33, ["string", "grid spacing"], 68, 226, [32, null]],
+[34, ["number", 32], 68, 268, [32, null]],
+[35, ["setxy2", 20], 1240, 856, [65, 38, 42, 66]],
+[36, "xcor", 1352, 856, [38, null]],
+[37, "ycor", 1352, 658, [39, null]],
+[38, ["plus2", 0], 1298, 856, [35, 36, 55]],
+[39, ["plus2", 0], 1298, 658, [40, 37, 53]],
+[40, ["setxy2", 20], 1240, 576, [63, 62, 39, 64]],
+[41, "leftpos", 1352, 576, [62, null]],
+[42, "ycor", 1298, 938, [35, null]],
+[43, "hat", 1240, 760, [null, 44, 65]],
+[44, ["string", "inc x"], 1298, 772, [43, null]],
+[45, "hat", 1240, 480, [null, 46, 63]],
+[46, ["string", "inc y"], 1298, 492, [45, null]],
+[47, ["vspace", 0], 18, 764, [23, 17]],
+[48, ["vspace", 0], 36, 848, [17, 18]],
+[49, "stack", 36, 1058, [15, 50, null]],
+[50, ["string", "inc x"], 94, 1058, [49, null]],
+[51, "stack", 18, 1118, [17, 52, null]],
+[52, ["string", "inc y"], 76, 1118, [51, null]],
+[53, "box", 1352, 700, [39, 54, null]],
+[54, ["string", "grid spacing"], 1407, 700, [53, null]],
+[55, "box", 1352, 898, [38, 56, null]],
+[56, ["string", "grid spacing"], 1407, 898, [55, null]],
+[57, ["storein", 0], 640, 598, [3, 58, 59, 138]],
+[58, ["string", "offset"], 708, 598, [57, null]],
+[59, ["number", 4], 708, 640, [57, null]],
+[60, "box", 1352, 618, [62, 61, null]],
+[61, ["string", "offset"], 1407, 618, [60, null]],
+[62, ["plus2", 0], 1298, 576, [40, 41, 60]],
+[63, "penup", 1240, 534, [45, 40]],
+[64, "pendown", 1240, 700, [40, null]],
+[65, "penup", 1240, 814, [43, 35]],
+[66, "pendown", 1240, 980, [35, null]],
+[67, "setcolor", 300, 276, [69, 71, 74]],
+[68, "setgray", 300, 360, [74, 77, null]],
+[69, "setshade", 300, 234, [75, 70, 67]],
+[70, ["number", 50], 385, 234, [69, null]],
+[71, ["random", 0], 377, 276, [67, 72, 73, null]],
+[72, ["number", 5], 463, 276, [71, null]],
+[73, ["number", 15], 463, 318, [71, null]],
+[74, ["vspace", 0], 300, 318, [67, 68]],
+[75, "hat", 300, 180, [null, 76, 69]],
+[76, ["string", "color 1"], 358, 192, [75, null]],
+[77, ["random", 0], 373, 360, [68, 78, 79, null]],
+[78, ["number", 80], 459, 360, [77, null]],
+[79, ["number", 100], 459, 402, [77, null]],
+[80, "stack", 36, 974, [22, 92, 15]],
+[81, ["string", "color 1"], 368, 724, [90, null]],
+[82, "hat", 0, 460, [null, 83, 128]],
+[83, ["string", "grid"], 58, 472, [82, null]],
+[84, "hat", 940, 180, [null, 85, 94]],
+[85, ["string", "color 3"], 998, 192, [84, null]],
+[86, "hat", 620, 180, [null, 87, 105]],
+[87, ["string", "color 2"], 678, 192, [86, null]],
+[88, "stack", 300, 766, [90, 89, null]],
+[89, ["string", "grid"], 358, 766, [88, null]],
+[90, ["storein", 0], 300, 682, [152, 91, 81, 88]],
+[91, ["string", "color scheme"], 368, 682, [90, null]],
+[92, "box", 94, 974, [80, 93, null]],
+[93, ["string", "color scheme"], 149, 974, [92, null]],
+[94, "setshade", 940, 234, [84, 95, 96]],
+[95, ["number", 50], 1025, 234, [94, null]],
+[96, "setcolor", 940, 276, [94, 97, 100]],
+[97, ["random", 0], 1017, 276, [96, 98, 99, null]],
+[98, ["number", 10], 1103, 276, [97, null]],
+[99, ["number", 20], 1103, 318, [97, null]],
+[100, ["vspace", 0], 940, 318, [96, 101]],
+[101, "setgray", 940, 360, [100, 102, null]],
+[102, ["random", 0], 1013, 360, [101, 103, 104, null]],
+[103, ["number", 80], 1099, 360, [102, null]],
+[104, ["number", 100], 1099, 402, [102, null]],
+[105, "setshade", 620, 234, [86, 106, 107]],
+[106, ["number", 40], 705, 234, [105, null]],
+[107, "setcolor", 620, 276, [105, 108, 111]],
+[108, ["random", 0], 697, 276, [107, 109, 110, null]],
+[109, ["number", 35], 783, 276, [108, null]],
+[110, ["number", 65], 783, 318, [108, null]],
+[111, ["vspace", 0], 620, 318, [107, 112]],
+[112, "setgray", 620, 360, [111, 113, null]],
+[113, ["random", 0], 693, 360, [112, 114, 115, null]],
+[114, ["number", 80], 779, 360, [113, null]],
+[115, ["number", 100], 779, 402, [113, null]],
+[116, "hat", 300, 460, [null, 117, 149]],
+[117, ["string", "grid 1"], 358, 472, [116, null]],
+[118, "hat", 640, 460, [null, 119, 3]],
+[119, ["string", "grid 2"], 698, 472, [118, null]],
+[120, "hat", 940, 460, [null, 121, 143]],
+[121, ["string", "grid 3"], 998, 472, [120, null]],
+[122, "stack", 0, 310, [32, 123, 124]],
+[123, ["string", "grid 1"], 58, 310, [122, null]],
+[124, "stack", 0, 352, [122, 125, 126]],
+[125, ["string", "grid 2"], 58, 352, [124, null]],
+[126, "stack", 0, 394, [124, 127, null]],
+[127, ["string", "grid 3"], 58, 394, [126, null]],
+[128, "penup", 0, 514, [82, 129]],
+[129, ["setxy2", 20], 0, 556, [128, 155, 156, 132]],
+[130, "leftpos", 112, 556, [155, null]],
+[131, "bottompos", 112, 638, [156, null]],
+[132, "pendown", 0, 680, [129, 23]],
+[133, ["storein", 0], 940, 682, [146, 134, 135, 136]],
+[134, ["string", "color scheme"], 1008, 682, [133, null]],
+[135, ["string", "color 3"], 1008, 724, [133, null]],
+[136, "stack", 940, 766, [133, 137, null]],
+[137, ["string", "grid"], 998, 766, [136, null]],
+[138, ["storein", 0], 640, 682, [57, 139, 140, 141]],
+[139, ["string", "color scheme"], 708, 682, [138, null]],
+[140, ["string", "color 2"], 708, 724, [138, null]],
+[141, "stack", 640, 766, [138, 142, null]],
+[142, ["string", "grid"], 698, 766, [141, null]],
+[143, ["storein", 0], 940, 514, [120, 144, 145, 146]],
+[144, ["string", "side"], 1008, 514, [143, null]],
+[145, ["number", 16], 1008, 556, [143, null]],
+[146, ["storein", 0], 940, 598, [143, 147, 148, 133]],
+[147, ["string", "offset"], 1008, 598, [146, null]],
+[148, ["number", 8], 1008, 640, [146, null]],
+[149, ["storein", 0], 300, 514, [116, 150, 151, 152]],
+[150, ["string", "side"], 368, 514, [149, null]],
+[151, ["number", 32], 368, 556, [149, null]],
+[152, ["storein", 0], 300, 598, [149, 153, 154, 90]],
+[153, ["string", "offset"], 368, 598, [152, null]],
+[154, ["number", 0], 368, 640, [152, null]],
+[155, ["plus2", 0], 58, 556, [129, 130, 157]],
+[156, ["plus2", 0], 58, 638, [129, 131, 159]],
+[157, "box", 112, 598, [155, 158, null]],
+[158, ["string", "offset"], 167, 598, [157, null]],
+[159, "box", 112, 680, [156, 160, null]],
+[160, ["string", "offset"], 167, 680, [159, null]]]
diff --git a/samples/thumbnails/graphics-grid.png b/samples/thumbnails/graphics-grid.png
new file mode 100644
index 0000000..bb6adf8
--- /dev/null
+++ b/samples/thumbnails/graphics-grid.png
Binary files differ