Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/plugins/turtle_blocks_extras/turtle_blocks_extras.py
diff options
context:
space:
mode:
authorWalter Bender <walter@sugarlabs.org>2013-11-13 22:42:18 (GMT)
committer Walter Bender <walter@sugarlabs.org>2013-11-13 22:42:18 (GMT)
commit6acdbc3db543f2692ee336a99722f5ab0b46c77e (patch)
tree97b84e77c63bddeb49bcb804e25e2457008f6a8d /plugins/turtle_blocks_extras/turtle_blocks_extras.py
parent3865e3c912f70fd7fcef2d20831a0231d30d96f1 (diff)
convert to new primitive type
Diffstat (limited to 'plugins/turtle_blocks_extras/turtle_blocks_extras.py')
-rw-r--r--plugins/turtle_blocks_extras/turtle_blocks_extras.py1150
1 files changed, 345 insertions, 805 deletions
diff --git a/plugins/turtle_blocks_extras/turtle_blocks_extras.py b/plugins/turtle_blocks_extras/turtle_blocks_extras.py
index e31cb27..1e9b2e4 100644
--- a/plugins/turtle_blocks_extras/turtle_blocks_extras.py
+++ b/plugins/turtle_blocks_extras/turtle_blocks_extras.py
@@ -15,8 +15,6 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-import gtk
-import gobject
from time import time
import os
import glob
@@ -24,37 +22,19 @@ import glob
from gettext import gettext as _
from plugins.plugin import Plugin
-from TurtleArt.tapalette import (make_palette, define_logo_function,
- block_names, block_primitives, special_names,
- content_blocks, palette_name_to_index,
- palette_names, palette_i18n_names)
-from TurtleArt.talogo import (primitive_dictionary, logoerror,
- media_blocks_dictionary)
-from TurtleArt.taconstants import (DEFAULT_SCALE, ICON_SIZE, CONSTANTS,
- MEDIA_SHAPES, SKIN_PATHS, BLOCKS_WITH_SKIN,
- PYTHON_SKIN, PREFIX_DICTIONARY, VOICES,
- MACROS, COLORDICT)
-from TurtleArt.tautils import (round_int, debug_output, get_path,
- data_to_string, find_group, image_to_base64,
- hat_on_top, listify, data_from_file,
- data_to_file, chooser_dialog, get_load_name)
-from TurtleArt.tajail import (myfunc, myfunc_import)
-
-
-def _num_type(x):
- """ Is x a number type? """
- if type(x) == int:
- return True
- if type(x) == float:
- return True
- if type(x) == ord:
- return True
- return False
-
-
-def _millisecond():
- """ Current time in milliseconds """
- return time() * 1000
+from TurtleArt.tapalette import (make_palette, define_logo_function)
+from TurtleArt.talogo import (primitive_dictionary, logoerror)
+from TurtleArt.taconstants import (CONSTANTS, MACROS, KEY_DICT, MEDIA_SHAPES,
+ REVERSE_KEY_DICT, SKIN_PATHS,
+ BLOCKS_WITH_SKIN, PYTHON_SKIN,
+ MEDIA_BLOCK2TYPE, VOICES)
+from TurtleArt.tautils import (debug_output, get_path, data_to_string,
+ hat_on_top, listify, data_from_file)
+from TurtleArt.taprimitive import (ArgSlot, ConstantArg, Primitive)
+from TurtleArt.tatype import (TYPE_BOOL, TYPE_BOX, TYPE_CHAR, TYPE_INT,
+ TYPE_FLOAT, TYPE_OBJECT, TYPE_STRING,
+ TYPE_NUMBER)
+from TurtleArt.taturtle import Turtle
class Turtle_blocks_extras(Plugin):
@@ -62,13 +42,13 @@ class Turtle_blocks_extras(Plugin):
from Turtle Art """
def __init__(self, turtle_window):
+ Plugin.__init__(self)
self.tw = turtle_window
def setup(self):
SKIN_PATHS.append('plugins/turtle_blocks_extras/images')
self.heap = self.tw.lc.heap
- self.keyboard = self.tw.lc.keyboard
self.title_height = int((self.tw.canvas.height / 20) * self.tw.scale)
# set up Turtle Block palettes
@@ -91,7 +71,6 @@ class Turtle_blocks_extras(Plugin):
colors=["#FFC000", "#A08000"],
help_string=_('Palette of flow operators'))
- # internally expanded macro
palette.add_block('while',
style='clamp-style-boolean',
label=_('while'),
@@ -100,8 +79,19 @@ class Turtle_blocks_extras(Plugin):
special_name=_('while'),
help_string=_('do-while-True operator that uses \
boolean operators from Numbers palette'))
+ self.tw.lc.def_prim(
+ 'while', 2,
+ Primitive(self.tw.lc.prim_loop,
+ arg_descs=[
+ ArgSlot(TYPE_OBJECT,
+ call_arg=False,
+ wrapper=Primitive(
+ Primitive.controller_while,
+ arg_descs=[ArgSlot(TYPE_BOOL,
+ call_arg=False)])),
+ ArgSlot(TYPE_OBJECT)]),
+ True)
- # internally expanded macro
palette.add_block('until',
style='clamp-style-boolean',
label=_('until'),
@@ -110,23 +100,39 @@ boolean operators from Numbers palette'))
special_name=_('until'),
help_string=_('do-until-True operator that uses \
boolean operators from Numbers palette'))
+ self.tw.lc.def_prim(
+ 'until', 2,
+ Primitive(self.tw.lc.prim_loop,
+ arg_descs=[
+ ArgSlot(TYPE_OBJECT,
+ call_arg=False,
+ # TODO can we use controller_while in
+ # combination with not_?
+ wrapper=Primitive(
+ Primitive.controller_until,
+ arg_descs=[ArgSlot(TYPE_BOOL,
+ call_arg=False)])),
+ ArgSlot(TYPE_OBJECT)]),
+ True)
- primitive_dictionary['clamp'] = self._prim_clamp
palette.add_block('sandwichclamp',
style='clamp-style-collapsible',
label=' ',
special_name=_('top'),
prim_name='clamp',
help_string=_('top of a collapsible stack'))
- self.tw.lc.def_prim('clamp', 1, primitive_dictionary['clamp'], True)
+ self.tw.lc.def_prim('clamp', 1,
+ Primitive(self.tw.lc.prim_clamp,
+ arg_descs=[ArgSlot(TYPE_OBJECT)]),
+ True)
def _media_palette(self):
- debug_output('creating %s palette' % _('media'),
- self.tw.running_sugar)
+
palette = make_palette('media',
colors=["#A0FF00", "#80A000"],
help_string=_('Palette of media objects'),
- position=7)
+ position=7,
+ translation=_('media'))
palette.add_block('journal',
style='box-style-media',
@@ -134,7 +140,7 @@ boolean operators from Numbers palette'))
default='None',
special_name=_('journal'),
help_string=_('Sugar Journal media object'))
- PREFIX_DICTIONARY['journal'] = '#smedia_'
+ MEDIA_BLOCK2TYPE['journal'] = 'media'
BLOCKS_WITH_SKIN.append('journal')
MEDIA_SHAPES.append('journalsmall')
MEDIA_SHAPES.append('journaloff')
@@ -147,7 +153,7 @@ boolean operators from Numbers palette'))
default='None',
help_string=_('Sugar Journal audio object'))
BLOCKS_WITH_SKIN.append('audio')
- PREFIX_DICTIONARY['audio'] = '#saudio_'
+ MEDIA_BLOCK2TYPE['audio'] = 'audio'
MEDIA_SHAPES.append('audiosmall')
MEDIA_SHAPES.append('audiooff')
MEDIA_SHAPES.append('audioon')
@@ -159,7 +165,7 @@ boolean operators from Numbers palette'))
default='None',
help_string=_('Sugar Journal video object'))
BLOCKS_WITH_SKIN.append('video')
- PREFIX_DICTIONARY['video'] = '#svideo_'
+ MEDIA_BLOCK2TYPE['video'] = 'video'
MEDIA_SHAPES.append('videosmall')
MEDIA_SHAPES.append('videooff')
MEDIA_SHAPES.append('videoon')
@@ -171,7 +177,7 @@ boolean operators from Numbers palette'))
default='None',
help_string=_('Sugar Journal description field'))
BLOCKS_WITH_SKIN.append('description')
- PREFIX_DICTIONARY['description'] = '#sdescr_'
+ MEDIA_BLOCK2TYPE['description'] = 'descr'
MEDIA_SHAPES.append('descriptionsmall')
MEDIA_SHAPES.append('descriptionoff')
MEDIA_SHAPES.append('descriptionon')
@@ -183,7 +189,6 @@ boolean operators from Numbers palette'))
special_name=_('text'),
help_string=_('string value'))
- primitive_dictionary['show'] = self._prim_show
palette.add_block('show',
style='basic-style-1arg',
label=_('show'),
@@ -193,8 +198,9 @@ boolean operators from Numbers palette'))
help_string=_('draws text or show media from the \
Journal'))
self.tw.lc.def_prim('show', 1,
- lambda self, x:
- primitive_dictionary['show'](x, True))
+ Primitive(self.tw.lc.show,
+ arg_descs=[ArgSlot(TYPE_OBJECT),
+ ConstantArg(True)]))
palette.add_block('showaligned',
hidden=True,
@@ -207,10 +213,10 @@ Journal'))
help_string=_('draws text or show media from the \
Journal'))
self.tw.lc.def_prim('showaligned', 1,
- lambda self, x:
- primitive_dictionary['show'](x, False))
+ Primitive(self.tw.lc.show,
+ arg_descs=[ArgSlot(TYPE_OBJECT),
+ ConstantArg(False)]))
- primitive_dictionary['setscale'] = self._prim_setscale
palette.add_block('setscale',
style='basic-style-1arg',
label=_('set scale'),
@@ -218,11 +224,13 @@ Journal'))
default=33,
logo_command='setlabelheight',
help_string=_('sets the scale of media'))
- self.tw.lc.def_prim('setscale', 1,
- lambda self, x:
- primitive_dictionary['setscale'](x))
+ self.tw.lc.def_prim(
+ 'setscale', 1,
+ Primitive(self.tw.lc.set_scale,
+ arg_descs=[ArgSlot(TYPE_NUMBER)],
+ call_afterwards=lambda value: self.after_set(
+ 'scale', value)))
- primitive_dictionary['savepix'] = self._prim_save_picture
palette.add_block('savepix',
style='basic-style-1arg',
label=_('save picture'),
@@ -231,9 +239,9 @@ Journal'))
help_string=_('saves a picture to the Sugar \
Journal'))
self.tw.lc.def_prim('savepix', 1,
- lambda self, x: primitive_dictionary['savepix'](x))
+ Primitive(self.tw.save_as_image,
+ arg_descs=[ArgSlot(TYPE_STRING)]))
- primitive_dictionary['savesvg'] = self._prim_save_svg
palette.add_block('savesvg',
style='basic-style-1arg',
label=_('save SVG'),
@@ -242,7 +250,9 @@ Journal'))
help_string=_('saves turtle graphics as an SVG file \
in the Sugar Journal'))
self.tw.lc.def_prim('savesvg', 1,
- lambda self, x: primitive_dictionary['savesvg'](x))
+ Primitive(self.tw.save_as_image,
+ arg_descs=[ArgSlot(TYPE_STRING)],
+ kwarg_descs={'svg': ConstantArg(True)}))
palette.add_block('scale',
style='box-style',
@@ -251,7 +261,9 @@ in the Sugar Journal'))
value_block=True,
logo_command='labelsize',
help_string=_('holds current scale value'))
- self.tw.lc.def_prim('scale', 0, lambda self: self.tw.lc.scale)
+ self.tw.lc.def_prim('scale', 0,
+ Primitive(self.tw.lc.get_scale,
+ return_type=TYPE_NUMBER))
palette.add_block('mediawait',
style='basic-style-extended-vertical',
@@ -282,7 +294,6 @@ complete'))
help_string=_('resume playing video or audio'))
self.tw.lc.def_prim('mediaplay', 0, self.tw.lc.media_play, True)
- primitive_dictionary['speak'] = self._prim_speak
palette.add_block('speak',
style='basic-style-1arg',
label=_('speak'),
@@ -290,9 +301,9 @@ complete'))
default=_('hello'),
help_string=_('speaks text'))
self.tw.lc.def_prim('speak', 1,
- lambda self, x: primitive_dictionary['speak'](x))
+ Primitive(self.prim_speak,
+ arg_descs=[ArgSlot(TYPE_STRING)]))
- primitive_dictionary['sinewave'] = self._prim_sinewave
palette.add_block('sinewave',
style='basic-style-3arg',
# TRANS: pitch, duration, amplitude
@@ -303,18 +314,19 @@ complete'))
help_string=_('plays a sinewave at frequency, \
amplitude, and duration (in seconds)'))
self.tw.lc.def_prim('sinewave', 3,
- lambda self, x, y, z:
- primitive_dictionary['sinewave'](x, y, z))
+ Primitive(self.prim_sinewave,
+ arg_descs=[ArgSlot(TYPE_NUMBER),
+ ArgSlot(TYPE_NUMBER),
+ ArgSlot(TYPE_NUMBER)]))
def _sensor_palette(self):
- debug_output('creating %s palette' % _('sensor'),
- self.tw.running_sugar)
+
palette = make_palette('sensor',
colors=["#FF6060", "#A06060"],
help_string=_('Palette of sensor blocks'),
- position=6)
+ position=6,
+ translation=_('sensor'))
- primitive_dictionary['mousebutton'] = self._prim_mouse_button
palette.add_block('mousebutton',
hidden=True,
style='box-style',
@@ -324,9 +336,9 @@ amplitude, and duration (in seconds)'))
help_string=_('returns 1 if mouse button is \
pressed'))
self.tw.lc.def_prim('mousebutton', 0,
- lambda self: primitive_dictionary['mousebutton']())
+ Primitive(self.tw.get_mouse_flag,
+ return_type=TYPE_NUMBER))
- primitive_dictionary['mousebutton2'] = self._prim_mouse_button_bool
palette.add_block('mousebutton2',
style='boolean-block-style',
label=_('button down'),
@@ -335,10 +347,9 @@ pressed'))
help_string=_('returns True if mouse button is \
pressed'))
self.tw.lc.def_prim('mousebutton2', 0,
- lambda self:
- primitive_dictionary['mousebutton2']())
+ Primitive(self.tw.get_mouse_button,
+ return_type=TYPE_BOOL))
- primitive_dictionary['mousex'] = self._prim_mouse_x
palette.add_block('mousex',
style='box-style',
label=_('mouse x'),
@@ -346,10 +357,10 @@ pressed'))
value_block=True,
help_string=_('returns mouse x coordinate'))
self.tw.lc.def_prim('mousex', 0,
- lambda self:
- primitive_dictionary['mousex']())
+ Primitive(self.tw.get_mouse_x,
+ return_type=TYPE_NUMBER,
+ call_afterwards=self.after_mouse_x))
- primitive_dictionary['mousey'] = self._prim_mouse_y
palette.add_block('mousey',
style='box-style',
label=_('mouse y'),
@@ -357,10 +368,10 @@ pressed'))
value_block=True,
help_string=_('returns mouse y coordinate'))
self.tw.lc.def_prim('mousey', 0,
- lambda self:
- primitive_dictionary['mousey']())
+ Primitive(self.tw.get_mouse_y,
+ return_type=TYPE_NUMBER,
+ call_afterwards=self.after_mouse_y))
- primitive_dictionary['kbinput'] = self._prim_kbinput
palette.add_block('kbinput',
style='basic-style-extended-vertical',
label=_('query keyboard'),
@@ -368,9 +379,9 @@ pressed'))
help_string=_('query for keyboard input (results \
stored in keyboard block)'))
self.tw.lc.def_prim('kbinput', 0,
- lambda self: primitive_dictionary['kbinput']())
+ Primitive(self.tw.get_keyboard_input,
+ call_afterwards=self.after_keypress))
- primitive_dictionary['keyboard'] = self._prim_keyboard
palette.add_block('keyboard',
style='box-style',
label=_('keyboard'),
@@ -380,9 +391,9 @@ stored in keyboard block)'))
help_string=_('holds results of query-keyboard \
block as ASCII'))
self.tw.lc.def_prim('keyboard', 0,
- lambda self: primitive_dictionary['keyboard']())
+ Primitive(self.tw.get_keyboard,
+ return_type=TYPE_NUMBER))
- primitive_dictionary['readpixel'] = self._prim_readpixel
palette.add_block('readpixel',
style='basic-style-extended-vertical',
label=_('read pixel'),
@@ -391,9 +402,8 @@ block as ASCII'))
help_string=_('RGB color under the turtle is pushed \
to the stack'))
self.tw.lc.def_prim('readpixel', 0,
- lambda self: primitive_dictionary['readpixel']())
+ Primitive(Turtle.read_pixel))
- primitive_dictionary['see'] = self._prim_see
palette.add_block('see',
style='box-style',
label=_('turtle sees'),
@@ -402,9 +412,10 @@ to the stack'))
help_string=_('returns the color that the turtle \
"sees"'))
self.tw.lc.def_prim('see', 0,
- lambda self: primitive_dictionary['see']())
+ Primitive(Turtle.get_color_index,
+ return_type=TYPE_NUMBER,
+ call_afterwards=self.after_see))
- primitive_dictionary['time'] = self._prim_time
palette.add_block('time',
style='box-style',
label=_('time'),
@@ -412,18 +423,33 @@ to the stack'))
value_block=True,
help_string=_('elapsed time (in seconds) since \
program started'))
- self.tw.lc.def_prim('time', 0,
- lambda self: primitive_dictionary['time']())
+ self.tw.lc.def_prim(
+ 'time', 0,
+ Primitive(
+ Primitive.identity,
+ return_type=TYPE_INT,
+ arg_descs=[
+ ConstantArg(
+ Primitive(
+ int,
+ arg_descs=[ConstantArg(
+ Primitive(Primitive.minus,
+ arg_descs=[
+ ConstantArg(Primitive(time)),
+ ConstantArg(Primitive(
+ self.tw.lc.get_start_time))])
+ )]
+ ))],
+ call_afterwards=self.after_time))
def _extras_palette(self):
- debug_output('creating %s palette' % _('extras'),
- self.tw.running_sugar)
+
palette = make_palette('extras',
colors=["#FF0000", "#A00000"],
help_string=_('Palette of extra options'),
- position=8)
+ position=8,
+ translation=_('extras'))
- primitive_dictionary['push'] = self._prim_push
palette.add_block('push',
style='basic-style-1arg',
#TRANS: push adds a new item to the program stack
@@ -432,12 +458,14 @@ program started'))
logo_command='tapush',
help_string=_('pushes value onto FILO (first-in \
last-out heap)'))
- self.tw.lc.def_prim('push', 1,
- lambda self, x: primitive_dictionary['push'](x))
+ self.tw.lc.def_prim(
+ 'push', 1,
+ Primitive(self.tw.lc.heap.append,
+ arg_descs=[ArgSlot(TYPE_OBJECT)],
+ call_afterwards=self.after_push))
define_logo_function('tapush', 'to tapush :foo\nmake "taheap fput \
:foo :taheap\nend\nmake "taheap []\n')
- primitive_dictionary['printheap'] = self._prim_printheap
palette.add_block('printheap',
style='basic-style-extended-vertical',
label=_('show heap'),
@@ -445,12 +473,14 @@ last-out heap)'))
logo_command='taprintheap',
help_string=_('shows values in FILO (first-in \
last-out heap)'))
- self.tw.lc.def_prim('printheap', 0,
- lambda self: primitive_dictionary['printheap']())
+ self.tw.lc.def_prim(
+ 'printheap', 0,
+ Primitive(self.tw.print_,
+ arg_descs=[ConstantArg(Primitive(self.tw.lc.get_heap)),
+ ConstantArg(False)]))
define_logo_function('taprintheap', 'to taprintheap \nprint :taheap\n\
end\n')
- primitive_dictionary['clearheap'] = self._prim_emptyheap
palette.add_block('clearheap',
style='basic-style-extended-vertical',
label=_('empty heap'),
@@ -458,12 +488,12 @@ end\n')
logo_command='taclearheap',
help_string=_('emptys FILO (first-in-last-out \
heap)'))
- self.tw.lc.def_prim('clearheap', 0,
- lambda self: primitive_dictionary['clearheap']())
+ self.tw.lc.def_prim(
+ 'clearheap', 0,
+ Primitive(self.tw.lc.reset_heap, call_afterwards=self.after_pop))
define_logo_function('taclearheap', 'to taclearheap\nmake "taheap []\n\
end\n')
- primitive_dictionary['pop'] = self._prim_pop
palette.add_block('pop',
style='box-style',
#TRANS: pop removes a new item from the program stack
@@ -473,12 +503,13 @@ end\n')
logo_command='tapop',
help_string=_('pops value off FILO (first-in \
last-out heap)'))
- self.tw.lc.def_prim('pop', 0,
- lambda self: primitive_dictionary['pop']())
+ self.tw.lc.def_prim(
+ 'pop', 0,
+ Primitive(self.tw.lc.heap.pop, return_type=TYPE_BOX,
+ call_afterwards=self.after_pop))
define_logo_function('tapop', 'to tapop\nif emptyp :taheap [stop]\n\
make "tmp first :taheap\nmake "taheap butfirst :taheap\noutput :tmp\nend\n')
- primitive_dictionary['isheapempty'] = self._prim_is_heap_empty
palette.add_block('isheapempty',
hidden=True,
style='box-style',
@@ -486,10 +517,15 @@ make "tmp first :taheap\nmake "taheap butfirst :taheap\noutput :tmp\nend\n')
prim_name='isheapempty',
value_block=True,
help_string=_('returns True if heap is empty'))
- self.tw.lc.def_prim('isheapempty', 0,
- lambda self: primitive_dictionary['isheapempty']())
+ self.tw.lc.def_prim(
+ 'isheapempty', 0,
+ Primitive(int, return_type=TYPE_INT,
+ arg_descs=[ConstantArg(
+ Primitive(Primitive.not_, return_type=TYPE_BOOL,
+ arg_descs=[ConstantArg(
+ Primitive(self.tw.lc.get_heap,
+ return_type=TYPE_BOOL))]))]))
- primitive_dictionary['saveheap'] = self._prim_save_heap
palette.add_block('saveheap',
style='basic-style-1arg',
label=_('save heap to file'),
@@ -498,9 +534,9 @@ make "tmp first :taheap\nmake "taheap butfirst :taheap\noutput :tmp\nend\n')
help_string=_('saves FILO (first-in \
last-out heap) to a file'))
self.tw.lc.def_prim('saveheap', 1,
- lambda self, x: primitive_dictionary['saveheap'](x))
+ Primitive(self.tw.lc.save_heap,
+ arg_descs=[ArgSlot(TYPE_STRING)]))
- primitive_dictionary['loadheap'] = self._prim_load_heap
palette.add_block('loadheap',
style='basic-style-1arg',
label=_('load heap from file'),
@@ -509,20 +545,26 @@ last-out heap) to a file'))
help_string=_('loads FILO (first-in \
last-out heap) from a file'))
self.tw.lc.def_prim('loadheap', 1,
- lambda self, x: primitive_dictionary['loadheap'](x))
+ Primitive(self.tw.lc.load_heap,
+ arg_descs=[ArgSlot(TYPE_STRING)],
+ return_type=TYPE_STRING,
+ call_afterwards=self.after_push))
- primitive_dictionary['isheapempty2'] = self._prim_is_heap_empty_bool
palette.add_block('isheapempty2',
style='boolean-block-style',
label=_('empty heap?'),
prim_name='isheapempty2',
value_block=True,
help_string=_('returns True if heap is empty'))
- self.tw.lc.def_prim('isheapempty2', 0,
- lambda self:
- primitive_dictionary['isheapempty2']())
+ self.tw.lc.def_prim(
+ 'isheapempty2', 0,
+ # Python automatically converts the heap to a boolean in contexts
+ # where a boolean is needed
+ Primitive(Primitive.not_, return_type=TYPE_BOOL,
+ arg_descs=[ConstantArg(
+ Primitive(self.tw.lc.get_heap,
+ return_type=TYPE_BOOL))]))
- primitive_dictionary['print'] = self._prim_print
palette.add_block('comment',
style='basic-style-1arg',
label=_('comment'),
@@ -530,9 +572,9 @@ last-out heap) from a file'))
default=_('comment'),
string_or_number=True,
help_string=_('places a comment in your code'))
- self.tw.lc.def_prim('comment', 1,
- lambda self, x:
- primitive_dictionary['print'](x, True))
+ self.tw.lc.def_prim(
+ 'comment', 1,
+ Primitive(Primitive.comment, arg_descs=[ArgSlot(TYPE_STRING)]))
palette.add_block('print',
style='basic-style-1arg',
@@ -542,27 +584,32 @@ last-out heap) from a file'))
string_or_number=True,
help_string=_('prints value in status block at \
bottom of the screen'))
- self.tw.lc.def_prim('print', 1,
- lambda self, x:
- primitive_dictionary['print'](x, False))
+ self.tw.lc.def_prim(
+ 'print', 1,
+ Primitive(self.tw.print_,
+ arg_descs=[ArgSlot(TYPE_OBJECT), ConstantArg(False)]))
- primitive_dictionary['chr'] = self._prim_chr
palette.add_block('chr',
style='number-style-1arg',
label='chr',
prim_name='chr',
help_string=_('Python chr operator'))
- self.tw.lc.def_prim('chr', 1,
- lambda self, x: primitive_dictionary['chr'](x))
+ self.tw.lc.def_prim(
+ 'chr', 1,
+ Primitive(chr, return_type=TYPE_CHAR,
+ arg_descs=[ArgSlot(TYPE_INT)]))
- primitive_dictionary['int'] = self._prim_int
palette.add_block('int',
style='number-style-1arg',
label='int',
prim_name='int',
help_string=_('Python int operator'))
- self.tw.lc.def_prim('int', 1,
- lambda self, x: primitive_dictionary['int'](x))
+ self.tw.lc.def_prim(
+ 'int', 1,
+ # leave over the actual work to the type system, and just demand
+ # that the argument be converted to an integer
+ Primitive(Primitive.identity, return_type=TYPE_INT,
+ arg_descs=[ArgSlot(TYPE_INT)]))
palette.add_block('polar',
style='basic-style-extended-vertical',
@@ -572,7 +619,6 @@ bottom of the screen'))
self.tw.lc.def_prim('polar', 0,
lambda self: self.tw.set_polar(True))
- primitive_dictionary['myfunction'] = self._prim_myfunction
palette.add_block('myfunc1arg',
style='number-style-var-arg',
label=[_('Python'), 'f(x)', 'x'],
@@ -581,9 +627,10 @@ bottom of the screen'))
string_or_number=True,
help_string=_('a programmable block: used to add \
advanced single-variable math equations, e.g., sin(x)'))
- self.tw.lc.def_prim('myfunction', 2,
- lambda self, f, x:
- primitive_dictionary['myfunction'](f, [x]))
+ self.tw.lc.def_prim(
+ 'myfunction', 2,
+ Primitive(self.tw.lc.prim_myfunction, return_type=TYPE_FLOAT,
+ arg_descs=[ArgSlot(TYPE_STRING), ArgSlot(TYPE_FLOAT)]))
palette.add_block('myfunc2arg',
hidden=True,
@@ -595,9 +642,11 @@ advanced single-variable math equations, e.g., sin(x)'))
string_or_number=True,
help_string=_('a programmable block: used to add \
advanced multi-variable math equations, e.g., sqrt(x*x+y*y)'))
- self.tw.lc.def_prim('myfunction2', 3,
- lambda self, f, x, y:
- primitive_dictionary['myfunction'](f, [x, y]))
+ self.tw.lc.def_prim(
+ 'myfunction2', 3,
+ Primitive(self.tw.lc.prim_myfunction, return_type=TYPE_FLOAT,
+ arg_descs=[ArgSlot(TYPE_STRING), ArgSlot(TYPE_FLOAT),
+ ArgSlot(TYPE_FLOAT)]))
palette.add_block('myfunc3arg',
hidden=True,
@@ -609,9 +658,11 @@ advanced multi-variable math equations, e.g., sqrt(x*x+y*y)'))
string_or_number=True,
help_string=_('a programmable block: used to add \
advanced multi-variable math equations, e.g., sin(x+y+z)'))
- self.tw.lc.def_prim('myfunction3', 4,
- lambda self, f, x, y, z:
- primitive_dictionary['myfunction'](f, [x, y, z]))
+ self.tw.lc.def_prim(
+ 'myfunction3', 4,
+ Primitive(self.tw.lc.prim_myfunction, return_type=TYPE_FLOAT,
+ arg_descs=[ArgSlot(TYPE_STRING), ArgSlot(TYPE_FLOAT),
+ ArgSlot(TYPE_FLOAT), ArgSlot(TYPE_FLOAT)]))
palette.add_block('cartesian',
style='basic-style-extended-vertical',
@@ -621,7 +672,6 @@ advanced multi-variable math equations, e.g., sin(x+y+z)'))
self.tw.lc.def_prim('cartesian', 0,
lambda self: self.tw.set_cartesian(True))
- primitive_dictionary['userdefined'] = self._prim_myblock
palette.add_block('userdefined',
style='basic-style-var-arg',
label=' ',
@@ -632,8 +682,8 @@ advanced multi-variable math equations, e.g., sin(x+y+z)'))
help_string=_('runs code found in the tamyblock.py \
module found in the Journal'))
self.tw.lc.def_prim('userdefined', 1,
- lambda self, x:
- primitive_dictionary['userdefined']([x]))
+ Primitive(self.tw.lc.prim_myblock,
+ arg_descs=[ArgSlot(TYPE_OBJECT)]))
BLOCKS_WITH_SKIN.append('userdefined')
PYTHON_SKIN.append('userdefined')
@@ -649,8 +699,9 @@ module found in the Journal'))
help_string=_('runs code found in the tamyblock.py \
module found in the Journal'))
self.tw.lc.def_prim('userdefined2', 2,
- lambda self, x, y:
- primitive_dictionary['userdefined']([x, y]))
+ Primitive(self.tw.lc.prim_myblock,
+ arg_descs=[ArgSlot(TYPE_OBJECT),
+ ArgSlot(TYPE_OBJECT)]))
BLOCKS_WITH_SKIN.append('userdefined2args')
PYTHON_SKIN.append('userdefined2args')
@@ -666,15 +717,16 @@ module found in the Journal'))
help_string=_('runs code found in the tamyblock.py \
module found in the Journal'))
self.tw.lc.def_prim('userdefined3', 3,
- lambda self, x, y, z:
- primitive_dictionary['userdefined']([x, y, z]))
+ Primitive(self.tw.lc.prim_myblock,
+ arg_descs=[ArgSlot(TYPE_OBJECT),
+ ArgSlot(TYPE_OBJECT),
+ ArgSlot(TYPE_OBJECT)]))
BLOCKS_WITH_SKIN.append('userdefined3args')
PYTHON_SKIN.append('userdefined3args')
MEDIA_SHAPES.append('pythonsmall')
MEDIA_SHAPES.append('pythonoff')
MEDIA_SHAPES.append('pythonon')
- primitive_dictionary['loadblock'] = self._prim_load_block
palette.add_block('loadblock',
style='basic-style-var-arg',
label=_('load'),
@@ -682,8 +734,9 @@ module found in the Journal'))
default=_('forward'),
help_string=_('loads a block'))
self.tw.lc.def_prim('loadblock', 1,
- lambda self, x:
- primitive_dictionary['loadblock'](x))
+ Primitive(self.tw.prim_load_block,
+ export_me=False,
+ arg_descs=[ArgSlot(TYPE_STRING)]))
palette.add_block('loadblock2arg',
style='basic-style-var-arg',
@@ -694,8 +747,10 @@ module found in the Journal'))
default=[_('forward'), 100],
help_string=_('loads a block'))
self.tw.lc.def_prim('loadblock2', 2,
- lambda self, x, y:
- primitive_dictionary['loadblock']([x, y]))
+ Primitive(self.tw.prim_load_block,
+ export_me=False,
+ arg_descs=[ArgSlot(TYPE_STRING),
+ ArgSlot(TYPE_OBJECT)]))
palette.add_block('loadblock3arg',
style='basic-style-var-arg',
@@ -706,10 +761,12 @@ module found in the Journal'))
default=[_('setxy'), 0, 0],
help_string=_('loads a block'))
self.tw.lc.def_prim('loadblock3', 3,
- lambda self, x, y, z:
- primitive_dictionary['loadblock']([x, y, z]))
+ Primitive(self.tw.prim_load_block,
+ export_me=False,
+ arg_descs=[ArgSlot(TYPE_STRING),
+ ArgSlot(TYPE_OBJECT),
+ ArgSlot(TYPE_OBJECT)]))
- primitive_dictionary['loadpalette'] = self._prim_load_palette
palette.add_block('loadpalette',
style='basic-style-1arg',
string_or_number=True,
@@ -718,8 +775,9 @@ module found in the Journal'))
default=_('turtle'),
help_string=_('selects a palette'))
self.tw.lc.def_prim('loadpalette', 1,
- lambda self, x:
- primitive_dictionary['loadpalette'](x))
+ Primitive(self.tw.prim_load_palette,
+ export_me=False,
+ arg_descs=[ArgSlot(TYPE_STRING)]))
palette.add_block('addturtle',
style='basic-style-1arg',
@@ -729,52 +787,56 @@ module found in the Journal'))
string_or_number=True,
help_string=_('chooses which turtle to command'))
self.tw.lc.def_prim('addturtle', 1,
- lambda self, x:
- self.tw.turtles.set_turtle(x))
+ Primitive(self.tw.lc.prim_turtle,
+ arg_descs=[ArgSlot(TYPE_STRING)]))
- primitive_dictionary['turtlex'] = self._prim_turtle_x
palette.add_block('turtlex',
style='number-style-1arg',
label=_('turtle x'),
prim_name='turtlex',
default=['Yertle'],
help_string=_('Returns x coordinate of turtle'))
- self.tw.lc.def_prim('turtlex', 1,
- lambda self, t: primitive_dictionary['turtlex'](t))
+ self.tw.lc.def_prim(
+ 'turtlex', 1,
+ Primitive(self.tw.turtles.get_turtle_x,
+ arg_descs=[ArgSlot(TYPE_OBJECT)],
+ return_type=TYPE_BOX))
- primitive_dictionary['turtley'] = self._prim_turtle_y
palette.add_block('turtley',
style='number-style-1arg',
label=_('turtle y'),
prim_name='turtley',
default=['Yertle'],
help_string=_('Returns y coordinate of turtle'))
- self.tw.lc.def_prim('turtley', 1,
- lambda self, t: primitive_dictionary['turtley'](t))
+ self.tw.lc.def_prim(
+ 'turtley', 1,
+ Primitive(self.tw.turtles.get_turtle_y,
+ arg_descs=[ArgSlot(TYPE_OBJECT)],
+ return_type=TYPE_BOX))
- primitive_dictionary['activeturtle'] = self._prim_active_turtle
palette.add_block('activeturtle',
style='box-style',
- #TRANS: pop removes a new item from the program stack
label=_('active turtle'),
prim_name='activeturtle',
value_block=True,
help_string=_('the name of the active turtle'))
- self.tw.lc.def_prim('activeturtle', 0,
- lambda self:
- primitive_dictionary['activeturtle']())
+ self.tw.lc.def_prim(
+ 'activeturtle', 0,
+ Primitive(Turtle.get_name,
+ return_type=TYPE_BOX))
- primitive_dictionary['turtleh'] = self._prim_turtle_h
palette.add_block('turtleh',
style='number-style-1arg',
label=_('turtle heading'),
prim_name='turtleh',
default=['Yertle'],
help_string=_('Returns heading of turtle'))
- self.tw.lc.def_prim('turtleh', 1,
- lambda self, t: primitive_dictionary['turtleh'](t))
+ self.tw.lc.def_prim(
+ 'turtleh', 1,
+ Primitive(self.tw.turtles.get_turtle_heading,
+ arg_descs=[ArgSlot(TYPE_OBJECT)],
+ return_type=TYPE_BOX))
- primitive_dictionary['skin'] = self._prim_reskin
palette.add_block('skin',
hidden=True,
colors=["#FF0000", "#A00000"],
@@ -783,8 +845,8 @@ module found in the Journal'))
prim_name='skin',
help_string=_("put a custom 'shell' on the turtle"))
self.tw.lc.def_prim('skin', 1,
- lambda self, x:
- primitive_dictionary['skin'](x))
+ Primitive(self.tw.lc.reskin,
+ arg_descs=[ArgSlot(TYPE_OBJECT)]))
# macro
palette.add_block('reskin',
@@ -801,39 +863,40 @@ module found in the Journal'))
help_string=_('top of a collapsed stack'))
def _portfolio_palette(self):
- debug_output('creating %s palette' % _('portfolio'),
- self.tw.running_sugar)
+
palette = make_palette('portfolio',
colors=["#0606FF", "#0606A0"],
help_string=_('Palette of presentation \
templates'),
- position=9)
+ position=9,
+ translation=_('portfolio'))
- primitive_dictionary['hideblocks'] = self._prim_hideblocks
palette.add_block('hideblocks',
style='basic-style-extended-vertical',
label=_('hide blocks'),
prim_name='hideblocks',
help_string=_('declutters canvas by hiding blocks'))
- self.tw.lc.def_prim('hideblocks', 0,
- lambda self: primitive_dictionary['hideblocks']())
+ self.tw.lc.def_prim(
+ 'hideblocks', 0,
+ Primitive(self._prim_hideblocks, export_me=False))
- primitive_dictionary['showblocks'] = self._prim_showblocks
palette.add_block('showblocks',
style='basic-style-extended-vertical',
label=_('show blocks'),
prim_name='showblocks',
help_string=_('restores hidden blocks'))
- self.tw.lc.def_prim('showblocks', 0,
- lambda self: primitive_dictionary['showblocks']())
+ self.tw.lc.def_prim(
+ 'showblocks', 0,
+ Primitive(self._prim_showblocks, export_me=False))
palette.add_block('fullscreen',
style='basic-style-extended-vertical',
label=_('Fullscreen').lower(),
prim_name='fullscreen',
help_string=_('hides the Sugar toolbars'))
- self.tw.lc.def_prim('fullscreen', 0,
- lambda self: self.tw.set_fullscreen())
+ self.tw.lc.def_prim(
+ 'fullscreen', 0,
+ Primitive(self.tw.set_fullscreen, export_me=False))
primitive_dictionary['bulletlist'] = self._prim_list
palette.add_block('list',
@@ -898,7 +961,10 @@ Journal objects'))
prim_name='lpos',
logo_command='lpos',
help_string=_('xcor of left of screen'))
- self.tw.lc.def_prim('lpos', 0, lambda self: CONSTANTS['leftpos'])
+ self.tw.lc.def_prim(
+ 'lpos', 0,
+ Primitive(CONSTANTS.get, return_type=TYPE_INT,
+ arg_descs=[ConstantArg('leftpos')]))
palette.add_block('bottompos',
style='box-style',
@@ -906,7 +972,10 @@ Journal objects'))
prim_name='bpos',
logo_command='bpos',
help_string=_('ycor of bottom of screen'))
- self.tw.lc.def_prim('bpos', 0, lambda self: CONSTANTS['bottompos'])
+ self.tw.lc.def_prim(
+ 'bpos', 0,
+ Primitive(CONSTANTS.get, return_type=TYPE_INT,
+ arg_descs=[ConstantArg('bottompos')]))
palette.add_block('width',
style='box-style',
@@ -914,7 +983,10 @@ Journal objects'))
prim_name='hres',
logo_command='width',
help_string=_('the canvas width'))
- self.tw.lc.def_prim('hres', 0, lambda self: CONSTANTS['width'])
+ self.tw.lc.def_prim(
+ 'hres', 0,
+ Primitive(CONSTANTS.get, return_type=TYPE_INT,
+ arg_descs=[ConstantArg('width')]))
palette.add_block('rightpos',
style='box-style',
@@ -922,7 +994,10 @@ Journal objects'))
prim_name='rpos',
logo_command='rpos',
help_string=_('xcor of right of screen'))
- self.tw.lc.def_prim('rpos', 0, lambda self: CONSTANTS['rightpos'])
+ self.tw.lc.def_prim(
+ 'rpos', 0,
+ Primitive(CONSTANTS.get, return_type=TYPE_INT,
+ arg_descs=[ConstantArg('rightpos')]))
palette.add_block('toppos',
style='box-style',
@@ -930,7 +1005,10 @@ Journal objects'))
prim_name='tpos',
logo_command='tpos',
help_string=_('ycor of top of screen'))
- self.tw.lc.def_prim('tpos', 0, lambda self: CONSTANTS['toppos'])
+ self.tw.lc.def_prim(
+ 'tpos', 0,
+ Primitive(CONSTANTS.get, return_type=TYPE_INT,
+ arg_descs=[ConstantArg('toppos')]))
palette.add_block('height',
style='box-style',
@@ -938,7 +1016,10 @@ Journal objects'))
prim_name='vres',
logo_command='height',
help_string=_('the canvas height'))
- self.tw.lc.def_prim('vres', 0, lambda self: CONSTANTS['height'])
+ self.tw.lc.def_prim(
+ 'vres', 0,
+ Primitive(CONSTANTS.get, return_type=TYPE_INT,
+ arg_descs=[ConstantArg('height')]))
palette.add_block('titlex',
hidden=True,
@@ -947,7 +1028,10 @@ Journal objects'))
label=_('title x'),
logo_command='titlex',
prim_name='titlex')
- self.tw.lc.def_prim('titlex', 0, lambda self: CONSTANTS['titlex'])
+ self.tw.lc.def_prim(
+ 'titlex', 0,
+ Primitive(CONSTANTS.get, return_type=TYPE_INT,
+ arg_descs=[ConstantArg('titlex')]))
palette.add_block('titley',
hidden=True,
@@ -956,7 +1040,10 @@ Journal objects'))
label=_('title y'),
logo_command='titley',
prim_name='titley')
- self.tw.lc.def_prim('titley', 0, lambda self: CONSTANTS['titley'])
+ self.tw.lc.def_prim(
+ 'titley', 0,
+ Primitive(CONSTANTS.get, return_type=TYPE_INT,
+ arg_descs=[ConstantArg('titley')]))
palette.add_block('leftx',
hidden=True,
@@ -965,7 +1052,10 @@ Journal objects'))
label=_('left x'),
prim_name='leftx',
logo_command='leftx')
- self.tw.lc.def_prim('leftx', 0, lambda self: CONSTANTS['leftx'])
+ self.tw.lc.def_prim(
+ 'leftx', 0,
+ Primitive(CONSTANTS.get, return_type=TYPE_INT,
+ arg_descs=[ConstantArg('leftx')]))
palette.add_block('topy',
hidden=True,
@@ -974,7 +1064,10 @@ Journal objects'))
label=_('top y'),
prim_name='topy',
logo_command='topy')
- self.tw.lc.def_prim('topy', 0, lambda self: CONSTANTS['topy'])
+ self.tw.lc.def_prim(
+ 'topy', 0,
+ Primitive(CONSTANTS.get, return_type=TYPE_INT,
+ arg_descs=[ConstantArg('topy')]))
palette.add_block('rightx',
hidden=True,
@@ -983,7 +1076,10 @@ Journal objects'))
label=_('right x'),
prim_name='rightx',
logo_command='rightx')
- self.tw.lc.def_prim('rightx', 0, lambda self: CONSTANTS['rightx'])
+ self.tw.lc.def_prim(
+ 'rightx', 0,
+ Primitive(CONSTANTS.get, return_type=TYPE_INT,
+ arg_descs=[ConstantArg('rightx')]))
palette.add_block('bottomy',
hidden=True,
@@ -992,7 +1088,10 @@ Journal objects'))
label=_('bottom y'),
prim_name='bottomy',
logo_command='bottomy')
- self.tw.lc.def_prim('bottomy', 0, lambda self: CONSTANTS['bottomy'])
+ self.tw.lc.def_prim(
+ 'bottomy', 0,
+ Primitive(CONSTANTS.get, return_type=TYPE_INT,
+ arg_descs=[ConstantArg('bottomy')]))
def _myblocks_palette(self):
''' User-defined macros are saved as a json-encoded file;
@@ -1002,12 +1101,11 @@ Journal objects'))
os.path.exists(self.tw.macros_path):
files = glob.glob(os.path.join(self.tw.macros_path, '*.tb'))
if len(files) > 0:
- debug_output('creating %s palette' % _('my blocks'),
- self.tw.running_sugar)
palette = make_palette(
- 'my blocks',
+ 'myblocks',
colors=["#FFFF00", "#A0A000"],
- help_string=_('Palette of user-defined operators'))
+ help_string=_('Palette of user-defined operators'),
+ translation=_('my blocks'))
for tafile in files:
data = data_from_file(tafile)
@@ -1020,360 +1118,36 @@ Journal objects'))
# Block primitives
- def _prim_emptyheap(self):
- """ Empty FILO """
- self.tw.lc.heap = []
-
- def _prim_keyboard(self):
- """ Return last character typed """
- return self.tw.lc.keyboard
-
- def _prim_kbinput(self):
- """ Query keyboard """
- DICT = {
- 'Left': 1,
- 'KP_Left': 1,
- 'Up': 2,
- 'KP_Up': 2,
- 'Right': 3,
- 'KP_Right': 3,
- 'Down': 4,
- 'KP_Down': 4,
- 'BackSpace': 8,
- 'Tab': 9,
- 'Return': 13,
- 'Escape': 27,
- 'space': 32,
- ' ': 32,
- 'exclam': 33,
- 'quotedbl': 34,
- 'numbersign': 35,
- 'dollar': 36,
- 'percent': 37,
- 'ampersand': 38,
- 'apostrophe': 39,
- 'parenleft': 40,
- 'parenright': 41,
- 'asterisk': 42,
- 'plus': 43,
- 'comma': 44,
- 'minus': 45,
- 'period': 46,
- 'slash': 47,
- 'colon': 58,
- 'semicolon': 59,
- 'less': 60,
- 'equal': 61,
- 'greater': 62,
- 'question': 63,
- 'at': 64,
- 'underscore': 95,
- 'bracketleft': 91,
- 'backslash': 92,
- 'bracketright': 93,
- 'asciicircum': 94,
- 'grave': 96,
- 'braceleft': 123,
- 'bar': 124,
- 'braceright': 125,
- 'asciitilde': 126,
- 'Delete': 127,
- }
- REVERSE_DICT = {
- 1: _('left'),
- 2: _('up'),
- 3: _('right'),
- 4: _('down'),
- 8: _('backspace'),
- 9: _('tab'),
- # TRANS: enter is the name of the enter (or return) key
- 13: _('enter'),
- 27: 'esc',
- # TRANS: space is the name of the space key
- 32: _('space'),
- 127: _('delete')
- }
-
- if len(self.tw.keypress) == 1:
- self.tw.lc.keyboard = ord(self.tw.keypress[0])
- elif self.tw.keypress in DICT:
- self.tw.lc.keyboard = DICT[self.tw.keypress]
- else:
- self.tw.lc.keyboard = 0
+ def after_keypress(self):
if self.tw.lc.update_values:
- if self.tw.keypress in DICT:
- if DICT[self.tw.keypress] in REVERSE_DICT:
+ if self.tw.keypress in KEY_DICT:
+ if KEY_DICT[self.tw.keypress] in REVERSE_KEY_DICT:
self.tw.lc.update_label_value(
- 'keyboard', REVERSE_DICT[DICT[self.tw.keypress]])
+ 'keyboard', REVERSE_KEY_DICT[
+ KEY_DICT[self.tw.keypress]])
else:
- self.tw.lc.update_label_value('keyboard',
- chr(DICT[self.tw.keypress]))
- elif self.tw.lc.keyboard > 0:
+ self.tw.lc.update_label_value(
+ 'keyboard', chr(KEY_DICT[self.tw.keypress]))
+ elif self.tw.keyboard > 0:
self.tw.lc.update_label_value('keyboard',
- chr(self.tw.lc.keyboard))
+ chr(self.tw.keyboard))
self.tw.keypress = ''
- def _prim_list(self, blklist):
- """ Expandable list block """
- self._prim_showlist(blklist)
- self.tw.lc.ireturn()
- yield True
-
- def _prim_myblock(self, x):
- """ Run Python code imported from Journal """
- if self.tw.lc.bindex is not None and \
- self.tw.lc.bindex in self.tw.myblock:
- try:
- if len(x) == 1:
- myfunc_import(self, self.tw.myblock[self.tw.lc.bindex],
- x[0])
- else:
- myfunc_import(self, self.tw.myblock[self.tw.lc.bindex], x)
- except:
- raise logoerror("#syntaxerror")
-
- def _prim_myfunction(self, f, x):
- """ Programmable block """
- for i, v in enumerate(x):
- if type(v) == int: # Pass float values to Python block
- x[i] = float(v)
- try:
- y = myfunc(f, x)
- if str(y) == 'nan':
- debug_output('Python function returned NAN',
- self.tw.running_sugar)
- self.tw.lc.stop_logo()
- raise logoerror("#notanumber")
- else:
- return y
- except ZeroDivisionError:
- self.tw.lc.stop_logo()
- raise logoerror("#zerodivide")
- except ValueError, e:
- self.tw.lc.stop_logo()
- raise logoerror('#' + str(e))
- except SyntaxError, e:
- self.tw.lc.stop_logo()
- raise logoerror('#' + str(e))
- except NameError, e:
- self.tw.lc.stop_logo()
- raise logoerror('#' + str(e))
- except OverflowError:
- self.tw.lc.stop_logo()
- raise logoerror("#overflowerror")
- except TypeError:
- self.tw.lc.stop_logo()
- raise logoerror("#notanumber")
-
- def _prim_is_heap_empty(self):
- """ is FILO empty? """
- if len(self.tw.lc.heap) == 0:
- return 1
- else:
- return 0
-
- def _prim_is_heap_empty_bool(self):
- """ is FILO empty? """
- if len(self.tw.lc.heap) == 0:
- return True
- else:
- return False
-
- def _prim_pop(self):
- """ Pop value off of FILO """
- if len(self.tw.lc.heap) == 0:
- raise logoerror("#emptyheap")
- else:
- if self.tw.lc.update_values:
- if len(self.tw.lc.heap) == 1:
- self.tw.lc.update_label_value('pop')
- else:
- self.tw.lc.update_label_value('pop', self.tw.lc.heap[-2])
- return self.tw.lc.heap.pop(-1)
-
- def _prim_print(self, n, flag):
- """ Print object n """
- if flag and (self.tw.hide or self.tw.step_time == 0):
- return
- if type(n) == list:
- self.tw.showlabel('print', n)
- elif type(n) == str or type(n) == unicode:
- if n in COLORDICT:
- if COLORDICT[n][0] is None:
- self.tw.showlabel('print', '%s %d, %s %d' %
- (_('shade'), COLORDICT[n][1],
- _('gray'), COLORDICT[n][2]))
- else:
- self.tw.showlabel('print', '%s %d, %s %d, %s %d' %
- (_('color'), COLORDICT[n][0],
- _('shade'), COLORDICT[n][1],
- _('gray'), COLORDICT[n][2]))
- elif n[0:6] == 'media_' and \
- n[6:].lower not in media_blocks_dictionary:
- try:
- if self.tw.running_sugar:
- from sugar.datastore import datastore
- try:
- dsobject = datastore.get(n[6:])
- except:
- debug_output("Couldn't open %s" % (n[6:]),
- self.tw.running_sugar)
- self.tw.showlabel('print', dsobject.metadata['title'])
- dsobject.destroy()
- else:
- self.tw.showlabel('print', n[6:])
- except IOError:
- self.tw.showlabel('print', n)
+ def after_pop(self, *ignored_args):
+ if self.tw.lc.update_values:
+ if not self.tw.lc.heap:
+ self.tw.lc.update_label_value('pop')
else:
- self.tw.showlabel('print', n)
- elif type(n) == int:
- self.tw.showlabel('print', n)
- else:
- self.tw.showlabel(
- 'print',
- str(round_int(n)).replace('.', self.tw.decimal_point))
-
- def _prim_printheap(self):
- """ Display contents of heap """
- heap_as_string = str(self.tw.lc.heap)
- if len(heap_as_string) > 80:
- self.tw.showlabel('print', str(self.tw.lc.heap)[0:79] + '…')
- else:
- self.tw.showlabel('print', str(self.tw.lc.heap))
-
- def _prim_load_heap(self, path):
- """ Load FILO from file """
- if type(path) == float:
- path = ''
- if self.tw.running_sugar:
- # Choose a datastore object and push data to heap (Sugar only)
- chooser_dialog(self.tw.parent, path,
- self.tw.lc.push_file_data_to_heap)
- else:
- if not os.path.exists(path):
- path, tw.load_save_folder = get_load_name(
- '.*', self.tw.load_save_folder)
- if path is None:
- return
-
- data = data_from_file(path)
- if data is not None:
- for val in data:
- self.tw.lc.heap.append(val)
-
- if len(self.tw.lc.heap) > 0:
- self.tw.lc.update_label_value('pop', self.tw.lc.heap[-1])
-
- def _prim_save_heap(self, path):
- """ save FILO to file """
- # TODO: add GNOME save
-
- if self.tw.running_sugar:
- from sugar import profile
- from sugar.datastore import datastore
- from sugar.activity import activity
-
- # Save JSON-encoded heap to temporary file
- heap_file = os.path.join(get_path(activity, 'instance'),
- str(path) + '.txt')
- data_to_file(self.tw.lc.heap, heap_file)
-
- # Create a datastore object
- dsobject = datastore.create()
-
- # Write any metadata (specifically set the title of the file
- # and specify that this is a plain text file).
- dsobject.metadata['title'] = str(path)
- dsobject.metadata['icon-color'] = profile.get_color().to_string()
- dsobject.metadata['mime_type'] = 'text/plain'
- dsobject.set_file_path(heap_file)
- datastore.write(dsobject)
- dsobject.destroy()
- else:
- heap_file = path
- data_to_file(self.tw.lc.heap, heap_file)
+ self.tw.lc.update_label_value('pop', self.tw.lc.heap[-1])
- def _prim_push(self, val):
- """ Push value onto FILO """
- self.tw.lc.heap.append(val)
+ def after_push(self, *ignored_args):
if self.tw.lc.update_values:
- self.tw.lc.update_label_value('pop', val)
-
- def _prim_readpixel(self):
- """ Read r, g, b, a from the canvas and push b, g, r to the stack """
- r, g, b, a = self.tw.turtles.get_active_turtle().get_pixel()
- self.tw.lc.heap.append(b)
- self.tw.lc.heap.append(g)
- self.tw.lc.heap.append(r)
-
- def _prim_active_turtle(self):
- return(self.tw.turtles.get_active_turtle().get_name())
-
- def _prim_reskin(self, media):
- """ Reskin the turtle with an image from a file """
- scale = int(ICON_SIZE * float(self.tw.lc.scale) / DEFAULT_SCALE)
- if scale < 1:
- return
- self.tw.lc.filepath = None
- dsobject = None
- if os.path.exists(media[6:]): # is it a path?
- self.tw.lc.filepath = media[6:]
- elif self.tw.running_sugar: # is it a datastore object?
- from sugar.datastore import datastore
- try:
- dsobject = datastore.get(media[6:])
- except:
- debug_output("Couldn't open skin %s" % (media[6:]),
- self.tw.running_sugar)
- if dsobject is not None:
- self.tw.lc.filepath = dsobject.file_path
- if self.tw.lc.filepath is None:
- self.tw.showlabel('nojournal', self.tw.lc.filepath)
- return
- pixbuf = None
- try:
- pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(self.tw.lc.filepath,
- scale, scale)
- except:
- self.tw.showlabel('nojournal', self.tw.lc.filepath)
- debug_output("Couldn't open skin %s" % (self.tw.lc.filepath),
- self.tw.running_sugar)
- if pixbuf is not None:
- self.tw.turtles.get_active_turtle().set_shapes([pixbuf])
- pen_state = self.tw.turtles.get_active_turtle().get_pen_state()
- if pen_state:
- self.tw.turtles.get_active_turtle().set_pen_state(False)
- self.tw.turtles.get_active_turtle().forward(0)
- if pen_state:
- self.tw.turtles.get_active_turtle().set_pen_state(True)
-
- if self.tw.sharing():
- if self.tw.running_sugar:
- tmp_path = get_path(self.tw.activity, 'instance')
+ if not self.tw.lc.heap:
+ self.tw.lc.update_label_value('pop')
else:
- tmp_path = '/tmp'
- tmp_file = os.path.join(get_path(self.tw.activity, 'instance'),
- 'tmpfile.png')
- pixbuf.save(tmp_file, 'png', {'quality': '100'})
- data = image_to_base64(tmp_file, tmp_path)
- height = pixbuf.get_height()
- width = pixbuf.get_width()
- event = 'R|%s' % (data_to_string([self.tw.nick,
- [round_int(width),
- round_int(height),
- data]]))
- gobject.idle_add(self.tw.send_event, event)
- os.remove(tmp_file)
-
- def _prim_save_picture(self, name):
- """ Save canvas to file as PNG """
- self.tw.save_as_image(name)
-
- def _prim_save_svg(self, name):
- """ Save SVG to file """
- self.tw.save_as_image(name, svg=True)
-
- def _prim_speak(self, text):
+ self.tw.lc.update_label_value('pop', self.tw.lc.heap[-1])
+
+ def prim_speak(self, text):
""" Speak text """
if type(text) == float and int(text) == text:
text = int(text)
@@ -1393,7 +1167,7 @@ Journal objects'))
language_option, text]))
self.tw.send_event(event)
- def _prim_sinewave(self, pitch, amplitude, duration):
+ def prim_sinewave(self, pitch, amplitude, duration):
""" Create a Csound score to play a sine wave. """
self.orchlines = []
self.scorelines = []
@@ -1467,139 +1241,34 @@ Journal objects'))
csd.write("\n</CsoundSynthesizer>")
csd.close()
- def _prim_mouse_x(self):
- """ Return mouse x coordinate """
- mousex = int(self.tw.mouse_x - (self.tw.canvas.width / 2))
+ def after_mouse_x(self):
+ """ Show mouse x coordinate """
if self.tw.lc.update_values:
- self.tw.lc.update_label_value('mousex', mousex)
- return mousex
+ self.tw.lc.update_label_value('mousex', self.tw.get_mouse_x())
- def _prim_mouse_y(self):
- """ Return mouse y coordinate """
- mousey = int((self.tw.canvas.height / 2) - self.tw.mouse_y)
+ def after_mouse_y(self):
+ """ Show mouse y coordinate """
if self.tw.lc.update_values:
- self.tw.lc.update_label_value('mousey', mousey)
- return mousey
+ self.tw.lc.update_label_value('mousey', self.tw.get_mouse_y())
- def _prim_mouse_button(self):
- """ Return 1 if mouse button is pressed """
- if self.tw.mouse_flag == 1:
- return 1
- else:
- return 0
-
- def _prim_mouse_button_bool(self):
- """ Return True if mouse button is pressed """
- if self.tw.mouse_flag == 1:
- return True
- else:
- return False
-
- def _prim_see(self):
- """ Read r, g, b from the canvas and return a corresponding palette
- color """
- r, g, b, a = self.tw.turtles.get_active_turtle().get_pixel()
- color_index = self.tw.canvas.get_color_index(r, g, b)
+ def after_see(self):
+ """ Show color under turtle """
if self.tw.lc.update_values:
- self.tw.lc.update_label_value('see', color_index)
- return color_index
+ self.tw.lc.update_label_value(
+ 'see',
+ self.tw.turtles.get_active_turtle().get_color_index())
- def _prim_setscale(self, scale):
- """ Set the scale used by the show block """
- self.tw.lc.scale = scale
- if self.tw.lc.update_values:
- self.tw.lc.update_label_value('scale', scale)
-
- def _prim_show(self, string, center=False):
- """ Show is the general-purpose media-rendering block. """
- if type(string) == str or type(string) == unicode:
- if string in ['media_', 'descr_', 'audio_', 'video_',
- 'media_None', 'descr_None', 'audio_None',
- 'video_None']:
- pass
- elif string[0:6] in ['media_', 'descr_', 'audio_', 'video_']:
- self.tw.lc.filepath = None
- self.tw.lc.pixbuf = None # Camera writes directly to pixbuf
- self.tw.lc.dsobject = None
- if string[6:].lower() in media_blocks_dictionary:
- media_blocks_dictionary[string[6:].lower()]()
- elif os.path.exists(string[6:]): # is it a path?
- self.tw.lc.filepath = string[6:]
- elif self.tw.running_sugar: # is it a datastore object?
- from sugar.datastore import datastore
- try:
- self.tw.lc.dsobject = datastore.get(string[6:])
- except:
- debug_output("Couldn't find dsobject %s" %
- (string[6:]), self.tw.running_sugar)
- if self.tw.lc.dsobject is not None:
- self.tw.lc.filepath = self.tw.lc.dsobject.file_path
- if self.tw.lc.pixbuf is not None:
- self.tw.lc.insert_image(center=center, pixbuf=True)
- elif self.tw.lc.filepath is None:
- if self.tw.lc.dsobject is not None:
- self.tw.showlabel(
- 'nojournal',
- self.tw.lc.dsobject.metadata['title'])
- else:
- self.tw.showlabel('nojournal', string[6:])
- debug_output("Couldn't open %s" % (string[6:]),
- self.tw.running_sugar)
- elif string[0:6] == 'media_':
- self.tw.lc.insert_image(center=center)
- elif string[0:6] == 'descr_':
- mimetype = None
- if self.tw.lc.dsobject is not None and \
- 'mime_type' in self.tw.lc.dsobject.metadata:
- mimetype = self.tw.lc.dsobject.metadata['mime_type']
- description = None
- if self.tw.lc.dsobject is not None and \
- 'description' in self.tw.lc.dsobject.metadata:
- description = self.tw.lc.dsobject.metadata[
- 'description']
- self.tw.lc.insert_desc(mimetype, description)
- elif string[0:6] == 'audio_':
- self.tw.lc.play_sound()
- elif string[0:6] == 'video_':
- self.tw.lc.play_video()
- if self.tw.lc.dsobject is not None:
- self.tw.lc.dsobject.destroy()
- else: # assume it is text to display
- x, y = self.tw.lc.x2tx(), self.tw.lc.y2ty()
- if center:
- y -= self.tw.canvas.textsize
- self.tw.turtles.get_active_turtle().draw_text(string, x, y,
- int(self.tw.canvas.textsize *
- self.tw.lc.scale / 100.),
- self.tw.canvas.width - x)
- elif type(string) == float or type(string) == int:
- string = round_int(string)
- x, y = self.tw.lc.x2tx(), self.tw.lc.y2ty()
- if center:
- y -= self.tw.canvas.textsize
- self.tw.turtles.get_active_turtle().draw_text(string, x, y,
- int(self.tw.canvas.textsize *
- self.tw.lc.scale / 100.),
- self.tw.canvas.width - x)
-
- 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)
- for s in sarray:
- self.tw.turtles.get_active_turtle().set_xy(x, y, pendown=False)
- self._prim_show(s)
- y -= int(self.tw.canvas.textsize * self.tw.lead)
-
- def _prim_time(self):
- """ Number of seconds since program execution has started or
- clean (prim_clear) block encountered """
- elapsed_time = int(time() - self.tw.lc.start_time)
+ def _prim_list(self, blklist):
+ """ Expandable list block """
+ self.tw.lc.showlist(blklist)
+ self.tw.lc.ireturn()
+ yield True
+
+ def after_time(self, elapsed_time):
+ """ Update the label of the 'time' block after computing the new
+ value. """
if self.tw.lc.update_values:
self.tw.lc.update_label_value('time', elapsed_time)
- return elapsed_time
def _prim_hideblocks(self):
""" hide blocks and show showblocks button """
@@ -1619,137 +1288,8 @@ Journal objects'))
self.tw.activity.stop_turtle_button.set_icon("stopiton")
self.tw.activity.stop_turtle_button.set_tooltip(_('Stop turtle'))
- def _prim_chr(self, x):
- """ Chr conversion """
- try:
- return chr(int(x))
- except ValueError:
- self.tw.lc.stop_logo()
- raise logoerror("#notanumber")
-
- def _prim_int(self, x):
- """ Int conversion """
- try:
- return int(x)
- except ValueError:
- self.tw.lc.stop_logo()
- raise logoerror("#notanumber")
-
- def _prim_turtle_x(self, t):
- """ Return x coordinate of turtle t """
- return self.tw.turtles.get_turtle_x(t)
-
- def _prim_turtle_y(self, t):
- """ Return y coordinate of turtle t """
- return self.tw.turtles.get_turtle_y(t)
-
- def _prim_turtle_h(self, t):
- """ Return heading of turtle t """
- return self.tw.turtles.get_turtle_heading(t)
-
- def _prim_clamp(self, blklist):
- """ Run clamp blklist """
- self.tw.lc.icall(self.tw.lc.evline, blklist[:])
- yield True
- self.tw.lc.procstop = False
- self.tw.lc.ireturn()
- yield True
-
- def _prim_load_block(self, blkname):
- ''' Load a block on to the canvas '''
- # Place the block at the active turtle (x, y) and move the turtle
- # into position to place the next block in the stack.
- # TODO: Add expandable argument
- pos = self.tw.turtles.get_active_turtle().get_xy()
- if isinstance(blkname, list):
- name = blkname[0]
- if len(blkname) > 1:
- value = blkname[1:]
- dy = int(self._find_block(name, pos[0], pos[1], value))
- else:
- dy = int(self._find_block(name, pos[0], pos[1]))
- else:
- name = blkname
- if name == 'delete':
- for blk in self.tw.just_blocks():
- if blk.status == 'load block':
- blk.type = 'trash'
- blk.spr.hide()
- dy = 0
- else:
- dy = int(self._find_block(name, pos[0], pos[1]))
-
- # Reposition turtle to end of flow
- pos = self.tw.turtles.get_active_turtle().get_xy()
- pos[1] -= dy
- self.tw.turtles.get_active_turtle().move_turtle(pos)
-
- def _make_block(self, name, x, y, defaults):
- if defaults is None:
- self.tw._new_block(name, x, y, defaults)
- else:
- for i, v in enumerate(defaults):
- if type(v) == float and int(v) == v:
- defaults[i] = int(v)
- self.tw._new_block(name, x, y, defaults)
-
- # Find the block we just created and attach it to a stack.
- self.tw.drag_group = None
- spr = self.tw.sprite_list.find_sprite((x, y))
- if spr is not None:
- blk = self.tw.block_list.spr_to_block(spr)
- if blk is not None:
- self.tw.drag_group = find_group(blk)
- for b in self.tw.drag_group:
- b.status = 'load block'
- self.tw._snap_to_dock()
-
- # Disassociate new block from mouse.
- self.tw.drag_group = None
- return blk.docks[-1][3]
-
- def _find_block(self, blkname, x, y, defaults=None):
- """ Create a new block. It is a bit more work than just calling
- _new_block(). We need to:
- (1) translate the label name into the internal block name;
- (2) 'dock' the block onto a stack where appropriate; and
- (3) disassociate the new block from the mouse. """
- x, y = self.tw.turtles.turtle_to_screen_coordinates((x, y))
- for name in block_names:
- # Translate label name into block/prim name.
- if blkname in block_names[name]: # block label is an array
- # print 'found a match', blkname, name, block_names[name]
- if name in content_blocks or \
- (name in block_primitives and
- block_primitives[name] == name):
- # print '_make_block', blkname, name
- return self._make_block(name, x, y, defaults)
- elif blkname in block_names:
- # print '_make_block', blkname
- return self._make_block(blkname, x, y, defaults)
- for name in special_names:
- # Translate label name into block/prim name.
- if blkname in special_names[name]:
- return self._make_block(name, x, y, defaults)
- # Check for a macro
- if blkname in MACROS:
- self.tw.new_macro(blkname, x, y)
- return 0 # Fix me: calculate flow position
- # Block not found
- raise logoerror("#syntaxerror")
- return -1
-
- def _prim_load_palette(self, arg):
- ''' Select a palette '''
- if type(arg) in [int, float]:
- if int(arg) < 0 or int(arg) > len(palette_names):
- raise logoerror("#syntaxerror")
- else:
- self.tw.show_toolbar_palette(int(arg))
- else:
- if type(arg) == unicode:
- arg = arg.encode('utf-8')
- if arg in palette_names or arg in palette_i18n_names:
- self.tw.show_toolbar_palette(palette_name_to_index(arg))
- else:
- raise logoerror("#syntaxerror")
+ def after_set(self, name, value=None):
+ ''' Update the associated value blocks '''
+ if value is not None:
+ if self.tw.lc.update_values:
+ self.tw.lc.update_label_value(name, value)