From ea3a04bb097a57621224e9894e02b1b0d13895cc Mon Sep 17 00:00:00 2001 From: Walter Bender Date: Tue, 01 Mar 2011 22:54:55 +0000 Subject: refactoring of palette and block generation: a class for each palette and block rather than giant dictionaries --- (limited to 'plugins') diff --git a/plugins/turtle_blocks_plugin.py b/plugins/turtle_blocks_plugin.py new file mode 100644 index 0000000..c7199f2 --- /dev/null +++ b/plugins/turtle_blocks_plugin.py @@ -0,0 +1,1202 @@ +# -*- coding: utf-8 -*- +#Copyright (c) 2011, Walter Bender + +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: + +#The above copyright notice and this permission notice shall be included in +#all copies or substantial portions of the Software. + +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +#THE SOFTWARE. + +import gtk +from time import time +import os.path +from gettext import gettext as _ + +try: + from sugar.datastore import datastore +except ImportError: + pass + +from plugin import Plugin +from TurtleArt.taprimitive import Palette, Primitive +from TurtleArt.talogo import PLUGIN_DICTIONARY, logoerror, \ + MEDIA_BLOCKS_DICTIONARY +from TurtleArt.taconstants import DEFAULT_SCALE, CONSTANTS, BLACK, WHITE, \ + ICON_SIZE +from TurtleArt.tautils import convert, round_int, debug_output +from TurtleArt.tajail import myfunc, myfunc_import + +# TODO: add expandibles to taprimitives +# fix position problem + + +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 _string_to_num(x): + """ Try to comvert a string to a number """ + xx = convert(x.replace(self.tw.decimal_point, '.'), float) + if type(xx) is float: + return xx + else: + xx, xflag = chr_to_ord(x) + if xflag: + return xx + else: + raise logoerror("#syntaxerror") + + +def _millisecond(): + """ Current time in milliseconds """ + return time() * 1000 + + +class Turtle_blocks_plugin(Plugin): + """ a class for defining the extra palettes that distinguish Turtle Blocks + from Turtle Art """ + + def __init__(self, parent): + self.tw = parent + + def setup(self): + # set up Turtle Block palettes + self._flow_palette() + + p = Palette('media', ["#A0FF00", "#80A000"]) + p.set_help(_('Palette of media objects')) + p.add_palette() + self._media_palette() + + p = Palette('sensor', ["#FF6060", "#A06060"]) + p.set_help(_('Palette of sensor blocks')) + p.add_palette() + self._sensor_palette() + + p = Palette('extras', ["#FF0000", "#A00000"]) + p.set_help(_('Palette of extra options')) + p.add_palette() + self._extras_palette() + + p = Palette('portfolio', ["#0606FF", "#0606A0"]) + p.set_help(_('Palette of presentation templates')) + p.add_palette() + self._portfolio_palette() + + def start(self): + pass + + def stop(self): + pass + + def goto_background(self): + pass + + def return_to_foreground(self): + pass + + def quit(self): + pass + + # Palette definitions + + def _flow_palette(self): + b = Primitive('while') # macro + b.set_palette('flow') + b.set_style('flow-style-boolean') + b.set_label(_('while')) + b.set_help(_('do-while-True operator that uses boolean operators from Numbers palette')) + b.add_prim() + + b = Primitive('until') # macro + b.set_palette('flow') + b.set_style('flow-style-boolean') + b.set_label(_('until')) + b.set_help(_('do-until-True operator that uses boolean operators from Numbers palette')) + b.add_prim() + + def _media_palette(self): + b = Primitive('journal') + b.set_palette('media') + b.set_style('box-style-media') + b.set_label(' ') + b.set_special_name(_('journal')) + b.set_default(None) + b.set_help(_('Sugar Journal media object')) + b.add_prim() + + b = Primitive('audio') + b.set_palette('media') + b.set_style('box-style-media') + b.set_label(' ') + b.set_special_name(_('audio')) + b.set_default(None) + b.set_help(_('Sugar Journal audio object')) + b.add_prim() + + b = Primitive('video') + b.set_palette('media') + b.set_style('box-style-media') + b.set_label(' ') + b.set_special_name(_('video')) + b.set_default(None) + b.set_help(_('Sugar Journal video object')) + b.add_prim() + + b = Primitive('description') + b.set_palette('media') + b.set_style('box-style-media') + b.set_label(' ') + b.set_special_name(_('description')) + b.set_default(None) + b.set_help(_('Sugar Journal description field')) + b.add_prim() + + b = Primitive('string') + b.set_palette('media') + b.set_style('box-style') + b.set_label(_('text')) + b.set_default(_('text')) + b.set_special_name('') + b.set_help('string value') + b.add_prim() + + b = Primitive('show') + b.set_palette('media') + b.set_style('basic-style-1arg') + b.set_label(_('show')) + b.set_default(_('text')) + b.set_prim_name('show') + b.set_help(_('draws text or show media from the Journal')) + PLUGIN_DICTIONARY['show'] = self._prim_show + self.tw.lc._def_prim('show', 1, + lambda self, x: PLUGIN_DICTIONARY['show'](x, True)) + b.add_prim() + + b = Primitive('showaligned') + b.set_style('basic-style-1arg') + b.set_label(_('show aligned')) + b.set_default(_('text')) + b.set_prim_name('showaligned') + b.set_help(_('draws text or show media from the Journal')) + self.tw.lc._def_prim('showaligned', 1, + lambda self, x: PLUGIN_DICTIONARY['show'](x, False)) + b.add_prim() + + b = Primitive('setscale') + b.set_palette('media') + b.set_style('basic-style-1arg') + b.set_label(_('set scale')) + b.set_prim_name('setscale') + b.set_default(33) + b.set_help(_('sets the scale of media')) + PLUGIN_DICTIONARY['setscale'] = self._prim_setscale + self.tw.lc._def_prim('setscale', 1, + lambda self, x: PLUGIN_DICTIONARY['setscale'](x)) + + b.add_prim() + + b = Primitive('savepix') + b.set_palette('media') + b.set_style('basic-style-1arg') + b.set_label(_('save picture')) + b.set_prim_name('savepix') + b.set_default(_('picture name')) + b.set_help(_('saves a picture to the Sugar Journal')) + PLUGIN_DICTIONARY['savepix'] = self._prim_save_picture + self.tw.lc._def_prim('savepix', 1, + lambda self, x: PLUGIN_DICTIONARY['savepix'](x)) + b.add_prim() + + b = Primitive('savesvg') + b.set_palette('media') + b.set_style('basic-style-1arg') + b.set_label(_('save SVG')) + b.set_prim_name('savesvg') + b.set_default(_('picture name')) + b.set_help(_('saves turtle graphics as an SVG file in the Sugar Journal')) + PLUGIN_DICTIONARY['savesvg'] = self._prim_save_svg + self.tw.lc._def_prim('savesvg', 1, + lambda self, x: PLUGIN_DICTIONARY['savesvg'](x)) + b.add_prim() + + b = Primitive('scale') + b.set_palette('media') + b.set_style('box-style') + b.set_label(_('scale')) + b.set_prim_name('scale') + b.set_value_block(True) + b.set_help(_('holds current scale value')) + self.tw.lc._def_prim('scale', 0, lambda self: self.tw.lc.scale) + b.add_prim() + + b = Primitive('mediawait') + b.set_palette('media') + b.set_style('basic-style-extended-vertical') + b.set_label(_('media wait')) + b.set_prim_name('mediawait') + b.set_help(_('wait for current video or audio to complete')) + self.tw.lc._def_prim('mediawait', 0, self.tw.lc._media_wait, True) + b.add_prim() + + def _sensor_palette(self): + b = Primitive('kbinput') + b.set_palette('sensor') + b.set_style('basic-style-extended-vertical') + b.set_label(_('query keyboard')) + b.set_prim_name('kbinput') + b.set_help(_('query for keyboard input (results stored in keyboard block)')) + PLUGIN_DICTIONARY['kbinput'] = self._prim_kbinput + self.tw.lc._def_prim('kbinput', 0, + lambda self: PLUGIN_DICTIONARY['kbinput']()) + b.add_prim() + + b = Primitive('keyboard') + b.set_palette('sensor') + b.set_style('box-style') + b.set_label(_('keyboard')) + b.set_prim_name('keyboard') + b.set_value_block(True) + b.set_help(_('holds results of query-keyboard block')) + self.tw.lc._def_prim('keyboard', 0, lambda self: self.tw.lc.keyboard) + b.add_prim() + + b = Primitive('readpixel') + b.set_palette('sensor') + b.set_style('basic-style-extended-vertical') + b.set_label(_('read pixel')) + b.set_prim_name('readpixel') + b.set_help(_('RGB color under the turtle is pushed to the stack')) + PLUGIN_DICTIONARY['readpixel'] = self._prim_readpixel + self.tw.lc._def_prim('readpixel', 0, + lambda self: PLUGIN_DICTIONARY['readpixel']()) + b.add_prim() + + b = Primitive('see') + b.set_palette('sensor') + b.set_style('box-style') + b.set_label(_('turtle sees')) + b.set_prim_name('see') + b.set_help(_('returns the color that the turtle "sees"')) + b.set_value_block(True) + PLUGIN_DICTIONARY['see'] = self._prim_see + self.tw.lc._def_prim('see', 0, + lambda self: PLUGIN_DICTIONARY['see']()) + b.add_prim() + + b = Primitive('time') + b.set_palette('sensor') + b.set_style('box-style') + b.set_label(_('time')) + b.set_prim_name('time') + b.set_value_block(True) + b.set_help(_('elapsed time (in seconds) since program started')) + PLUGIN_DICTIONARY['time'] = self._prim_time + self.tw.lc._def_prim('time', 0, + lambda self: PLUGIN_DICTIONARY['time']()) + b.add_prim() + + def _extras_palette(self): + b = Primitive('push') + b.set_palette('extras') + b.set_style('basic-style-1arg') + b.set_label(_('push')) + b.set_prim_name('push') + b.set_help(_('pushes value onto FILO (first-in last-out heap)')) + PLUGIN_DICTIONARY['push'] = self._prim_push + self.tw.lc._def_prim('push', 1, + lambda self, x: PLUGIN_DICTIONARY['push'](x)) + b.add_prim() + + b = Primitive('printheap') + b.set_palette('extras') + b.set_style('basic-style-extended-vertical') + b.set_label(_('show heap')) + b.set_prim_name('printheap') + b.set_help(_('shows values in FILO (first-in last-out heap)')) + PLUGIN_DICTIONARY['printheap'] = self._prim_printheap + self.tw.lc._def_prim('printheap', 0, + lambda self: PLUGIN_DICTIONARY['printheap']()) + b.add_prim() + + b = Primitive('clearheap') + b.set_palette('extras') + b.set_style('basic-style-extended-vertical') + b.set_label(_('empty heap')) + b.set_prim_name('clearheap') + b.set_help(_('emptys FILO (first-in-last-out heap)')) + PLUGIN_DICTIONARY['clearheap'] = self._prim_emptyheap + self.tw.lc._def_prim('clearheap', 0, + lambda self: PLUGIN_DICTIONARY['clearheap']()) + b.add_prim() + + b = Primitive('pop') + b.set_palette('extras') + b.set_style('box-style') + b.set_label(_('pop')) + b.set_prim_name('pop') + b.set_value_block(True) + b.set_help(_('pops value off FILO (first-in last-out heap)')) + PLUGIN_DICTIONARY['pop'] = self._prim_pop + self.tw.lc._def_prim('pop', 0, + lambda self: PLUGIN_DICTIONARY['pop']()) + b.add_prim() + + b = Primitive('comment') + b.set_palette('extras') + b.set_style('basic-style-1arg') + b.set_label(_('comment')) + b.set_prim_name('comment') + b.set_default(_('comment')) + b.set_help(_('places a comment in your code')) + PLUGIN_DICTIONARY['print'] = self._prim_print + self.tw.lc._def_prim('comment', 1, + lambda self, x: PLUGIN_DICTIONARY['print'](x, True)) + b.add_prim() + + b = Primitive('print') + b.set_palette('extras') + b.set_style('basic-style-1arg') + b.set_label(_('print')) + b.set_prim_name('print') + b.set_help(_('prints value in status block at bottom of the screen')) + self.tw.lc._def_prim('print', 1, + lambda self, x: PLUGIN_DICTIONARY['print'](x, False)) + b.add_prim() + + b = Primitive('myfunc1arg') + b.set_palette('extras') + b.set_style('number-style-var-arg') + b.set_label([_('Python'), 'f(x)', 'x']) + b.set_prim_name('myfunction') + b.set_default(['x', 100]) + b.set_help(_('a programmable block: used to add advanced single-variable math equations, e.g., sin(x)')) + PLUGIN_DICTIONARY['myfunction'] = self._prim_myfunction + self.tw.lc._def_prim('myfunction', 2, + lambda self, f, x: PLUGIN_DICTIONARY['myfunction'](f, [x])) + b.add_prim() + + b = Primitive('myfunc2arg') + b.set_style('number-style-var-arg') + b.set_label([_('Python'), 'f(x,y)', 'x']) + b.set_prim_name('myfunction2') + b.set_default(['x+y', 100, 100]) + b.set_help(_('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: PLUGIN_DICTIONARY['myfunction'](f, [x, y])) + b.add_prim() + + b = Primitive('myfunc3arg') + b.set_style('number-style-var-arg') + b.set_label([_('Python'), 'f(x,y,z)', 'x']) + b.set_prim_name('myfunction3') + b.set_default(['x+y+z', 100, 100, 100]) + b.set_help(_('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: PLUGIN_DICTIONARY['myfunction']( + f, [x, y, z])) + b.add_prim() + + b = Primitive('userdefined') + b.set_palette('extras') + b.set_style('basic-style-var-arg') + b.set_label(' ') + b.set_prim_name('userdefined') + b.set_special_name(_('Python block')) + b.set_default(100) + b.set_help(_('runs code found in the tamyblock.py module found in the Journal')) + PLUGIN_DICTIONARY['userdefined'] = self._prim_myblock + self.tw.lc._def_prim('userdefined', 1, + lambda self, x: PLUGIN_DICTIONARY['userdefined']([x])) + b.add_prim() + + b = Primitive('userdefined2') + b.set_style('basic-style-var-arg') + b.set_label(' ') + b.set_prim_name('userdefined') + b.set_special_name(_('Python block')) + b.set_default([100, 100]) + b.set_help(_('runs code found in the tamyblock.py module found in the Journal')) + self.tw.lc._def_prim('userdefined2', 2, + lambda self, x, y: PLUGIN_DICTIONARY['userdefined']([x, y])) + b.add_prim() + + b = Primitive('userdefined3') + b.set_style('basic-style-var-arg') + b.set_label(' ') + b.set_prim_name('userdefined') + b.set_special_name(_('Python block')) + b.set_default([100, 100, 100]) + b.set_help(_('runs code found in the tamyblock.py module found in the Journal')) + self.tw.lc._def_prim('userdefined3', 3, + lambda self, x, y, z: PLUGIN_DICTIONARY['userdefined']([x, y, z])) + b.add_prim() + + b = Primitive('cartesian') + b.set_palette('extras') + b.set_style('basic-style-extended-vertical') + b.set_label(_('Cartesian')) + b.set_prim_name('cartesian') + b.set_help(_('displays Cartesian coordinates')) + self.tw.lc._def_prim('cartesian', 0, + lambda self: self.tw.set_cartesian(True)) + b.add_prim() + + b = Primitive('polar') + b.set_palette('extras') + b.set_style('basic-style-extended-vertical') + b.set_label(_('polar')) + b.set_prim_name('polar') + b.set_help(_('displays polar coordinates')) + self.tw.lc._def_prim('polar', 0, + lambda self: self.tw.set_polar(True)) + b.add_prim() + + b = Primitive('addturtle') + b.set_palette('extras') + b.set_style('basic-style-1arg') + b.set_label(_('turtle')) + b.set_prim_name('turtle') + b.set_default(1) + b.set_help(_('chooses which turtle to command')) + self.tw.lc._def_prim('turtle', 1, + lambda self, x: self.tw.canvas.set_turtle(x)) + b.add_prim() + + b = Primitive('skin') + b.set_style('basic-style-1arg') + b.set_label(_('turtle shell')) + b.set_prim_name('skin') + b.set_help(_("put a custom 'shell' on the turtle")) + PLUGIN_DICTIONARY['skin'] = self._prim_reskin + self.tw.lc._def_prim('skin', 1, + lambda self, x: PLUGIN_DICTIONARY['skin'](x)) + b.add_prim() + + b = Primitive('reskin') # macro + b.set_palette('extras') + b.set_style('basic-style-1arg') + b.set_label(_('turtle shell')) + b.set_help(_("put a custom 'shell' on the turtle")) + b.add_prim() + + b = Primitive('sandwichtop_no_label') + b.set_palette('extras') + b.set_style('collapsible-top-no-label') + b.set_label([' ', ' ']) + b.set_prim_name('nop') + b.set_help(_('top of a collapsed stack')) + b.add_prim() + + b = Primitive('sandwichbottom') + b.set_palette('extras') + b.set_style('collapsible-bottom') + b.set_label([' ', ' ']) + b.set_prim_name('nop') + b.set_help(_('bottom of a collapsed stack')) + b.add_prim() + + b = Primitive('sandwichcollapsed') + b.set_style('invisible') + b.set_label(' ') + b.set_prim_name('nop') + b.set_help(_('bottom block in a collapsed stack: click to open')) + b.add_prim() + + b = Primitive('sandwichtop') # depreciated + b.set_style('collapsible-top') + b.set_label(_('top of stack')) + b.set_default(_('label')) + b.set_prim_name('comment') + b.set_help(_('top of stack')) + b.add_prim() + + b = Primitive('sandwichtop_no_arm') # depreciated + b.set_style('collapsible-top-no-arm') + b.set_label(_('top of a collapsible stack')) + b.set_default(_('label')) + b.set_prim_name('comment') + b.set_help(_('top of stack')) + b.add_prim() + + b = Primitive('sandwichtop_no_arm_no_label') # depreciated + b.set_style('collapsible-top-no-arm-no-label') + b.set_label([' ', _('click to open')]) + b.set_prim_name('nop') + b.set_help(_('top of stack')) + b.add_prim() + + def _portfolio_palette(self): + b = Primitive('hideblocks') + b.set_palette('portfolio') + b.set_style('basic-style-extended-vertical') + b.set_label(_('hide blocks')) + b.set_prim_name('hideblocks') + b.set_help(_('declutters canvas by hiding blocks')) + self.tw.lc._def_prim('hideblocks', 0, lambda self: self.tw.hideblocks()) + b.add_prim() + + b = Primitive('showblocks') + b.set_palette('portfolio') + b.set_style('basic-style-extended-vertical') + b.set_label(_('show blocks')) + b.set_prim_name('showblocks') + b.set_help(_('restores hidden blocks')) + self.tw.lc._def_prim('showblocks', 0, lambda self: self.tw.showblocks()) + b.add_prim() + + b = Primitive('fullscreen') + b.set_palette('portfolio') + b.set_style('basic-style-extended-vertical') + b.set_label(_('full screen')) + b.set_prim_name('fullscreen') + b.set_help(_('hides the Sugar toolbars')) + self.tw.lc._def_prim('fullscreen', 0, + lambda self: self.tw.set_fullscreen()) + b.add_prim() + + b = Primitive('picturelist') # macro + b.set_palette('portfolio') + b.set_style('basic-style-extended') + b.set_label(' ') + b.set_help(_('presentation template: list of bullets')) + b.add_prim() + + b = Primitive('picture1x1a') # macro + b.set_palette('portfolio') + b.set_style('basic-style-extended') + b.set_label(' ') + b.set_help(_('presentation template: select Journal object (no description)')) + b.add_prim() + + b = Primitive('picture1x1') # macro + b.set_palette('portfolio') + b.set_style('basic-style-extended') + b.set_label(' ') + b.set_help(_('presentation template: select Journal object (with description)')) + b.add_prim() + + b = Primitive('picture2x2') # macro + b.set_palette('portfolio') + b.set_style('basic-style-extended') + b.set_label(' ') + b.set_help(_('presentation template: select four Journal objects')) + b.add_prim() + + b = Primitive('picture2x1') # macro + b.set_palette('portfolio') + b.set_style('basic-style-extended') + b.set_label(' ') + b.set_help(_('presentation template: select two Journal objects')) + b.add_prim() + + b = Primitive('picture1x2') # macro + b.set_palette('portfolio') + b.set_style('basic-style-extended') + b.set_label(' ') + b.set_help(_('presentation template: select two Journal objects')) + b.add_prim() + + b = Primitive('leftpos') + b.set_palette('portfolio') + b.set_style('box-style') + b.set_label(_('left')) + b.set_prim_name('lpos') + b.set_help(_('xcor of left of screen')) + self.tw.lc._def_prim('lpos', 0, lambda self: CONSTANTS['leftpos']) + b.add_prim() + + b = Primitive('bottompos') + b.set_palette('portfolio') + b.set_style('box-style') + b.set_label(_('bottom')) + b.set_prim_name('bpos') + b.set_help(_('ycor of bottom of screen')) + self.tw.lc._def_prim('bpos', 0, lambda self: CONSTANTS['bottompos']) + b.add_prim() + + b = Primitive('width') + b.set_palette('portfolio') + b.set_style('box-style') + b.set_label(_('width')) + b.set_prim_name('hres') + b.set_help(_('the canvas width')) + self.tw.lc._def_prim('hres', 0, lambda self: CONSTANTS['width']) + b.add_prim() + + b = Primitive('rightpos') + b.set_palette('portfolio') + b.set_style('box-style') + b.set_label(_('right')) + b.set_prim_name('rpos') + b.set_help(_('xcor of right of screen')) + self.tw.lc._def_prim('rpos', 0, lambda self: CONSTANTS['rightpos']) + b.add_prim() + + b = Primitive('toppos') + b.set_palette('portfolio') + b.set_style('box-style') + b.set_label(_('top')) + b.set_prim_name('tpos') + b.set_help(_('ycor of top of screen')) + self.tw.lc._def_prim('tpos', 0, lambda self: CONSTANTS['toppos']) + b.add_prim() + + b = Primitive('height') + b.set_palette('portfolio') + b.set_style('box-style') + b.set_label(_('height')) + b.set_prim_name('vres') + b.set_help(_('the canvas height')) + self.tw.lc._def_prim('vres', 0, lambda self: CONSTANTS['height']) + b.add_prim() + + b = Primitive('titlex') + b.set_style('box-style') + b.set_label(_('title x')) + b.set_prim_name('titlex') + self.tw.lc._def_prim('titlex', 0, lambda self: CONSTANTS['titlex']) + b.add_prim() + + b = Primitive('titley') + b.set_style('box-style') + b.set_label(_('title y')) + b.set_prim_name('titley') + self.tw.lc._def_prim('titley', 0, lambda self: CONSTANTS['titley']) + b.add_prim() + + b = Primitive('leftx') + b.set_style('box-style') + b.set_label(_('left x')) + b.set_prim_name('leftx') + self.tw.lc._def_prim('leftx', 0, lambda self: CONSTANTS['leftx']) + b.add_prim() + + b = Primitive('topy') + b.set_style('box-style') + b.set_label(_('top y')) + b.set_prim_name('topy') + self.tw.lc._def_prim('topy', 0, lambda self: CONSTANTS['topy']) + b.add_prim() + + b = Primitive('rightx') + b.set_style('box-style') + b.set_label(_('right x')) + b.set_prim_name('rightx') + self.tw.lc._def_prim('rightx', 0, lambda self: CONSTANTS['rightx']) + b.add_prim() + + b = Primitive('bottomy') + b.set_style('box-style') + b.set_label(_('bottom y')) + b.set_prim_name('bottomy') + self.tw.lc._def_prim('bottomy', 0, lambda self: CONSTANTS['bottomy']) + b.add_prim() + + # Block primitives + + def _prim_emptyheap(self): + """ Empty FILO """ + self.tw.lc.heap = [] + + def _prim_kbinput(self): + """ Query keyboard """ + if len(self.tw.keypress) == 1: + self.tw.lc.keyboard = ord(self.tw.keypress[0]) + else: + try: + self.tw.lc.keyboard = {'Escape': 27, 'space': 32, ' ': 32, + 'Return': 13, 'KP_Up': 2, 'KP_Down': 4, 'KP_Left': 1, + 'KP_Right': 3}[self.tw.keypress] + except KeyError: + self.tw.lc.keyboard = 0 + self.tw.lc.update_label_value('keyboard', self.tw.lc.keyboard) + self.tw.keypress = '' + + 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 """ + 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_pop(self): + """ Pop value off of FILO """ + if len(self.tw.lc.heap) == 0: + raise logoerror("#emptyheap") + else: + 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) == str or type(n) == unicode: + if n[0:6] == 'media_' and \ + n[6:].lower not in MEDIA_BLOCKS_DICTIONARY: + try: + if self.tw.running_sugar: + try: + dsobject = datastore.get(n[6:]) + except: + debug_output("Couldn't open %s" % (n[6:]), + self.tw.running_sugar) + self.tw.showlabel('status', dsobject.metadata['title']) + dsobject.destroy() + else: + self.tw.showlabel('status', n[6:]) + except IOError: + self.tw.showlabel('status', n) + else: + self.tw.showlabel('status', n) + elif type(n) == int: + self.tw.showlabel('status', n) + else: + self.tw.showlabel('status', + str(round_int(n)).replace('.', self.tw.decimal_point)) + + def _prim_printheap(self): + """ Display contents of heap """ + self.tw.showlabel('status', str(self.tw.lc.heap) + ' ') + + def _prim_push(self, val): + """ Push value onto FILO """ + self.tw.lc.heap.append(val) + 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.canvas.get_pixel() + self.tw.lc.heap.append(b) + self.tw.lc.heap.append(g) + self.tw.lc.heap.append(r) + + 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? + 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 == None: + self.tw.showlabel('nojournal', self.tw.lc.filepath) + return + pixbuf = None + try: + print self.tw.lc.filepath, scale, scale + 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.active_turtle.set_shapes([pixbuf]) + pen_state = self.tw.active_turtle.get_pen_state() + if pen_state: + self.tw.canvas.setpen(False) + self.tw.canvas.forward(0) + if pen_state: + self.tw.canvas.setpen(True) + + 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.canvas.svg_close() + self.tw.save_as_image(name, True) + + def _prim_see(self): + """ Read r, g, b from the canvas and return a corresponding palette + color """ + r, g, b, a = self.tw.canvas.get_pixel() + color_index = self.tw.canvas.get_color_index(r, g, b) + self.tw.lc.update_label_value('see', color_index) + return color_index + + def _prim_setscale(self, scale): + """ Set the scale used by the show block """ + self.tw.lc.scale = scale + 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.dsobject = None + print string[6:], MEDIA_BLOCKS_DICTIONARY + 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? + 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.filepath == 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) + 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._x(), self.tw.lc._y() + if center: + y -= self.tw.canvas.textsize + self.tw.canvas.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._x(), self.tw.lc._y() + if center: + y -= self.tw.canvas.textsize + self.tw.canvas.draw_text(string, x, y, + int(self.tw.canvas.textsize * \ + self.tw.lc.scale / 100.), + self.tw.canvas.width - x) + + 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) + self.tw.lc.update_label_value('time', elapsed_time) + return elapsed_time + + # Depreciated blocks + + """ +PORTFOLIO_STYLE_2x2 = ['template2x2'] +PORTFOLIO_STYLE_1x1 = ['template1x1', 'template1x1a'] +PORTFOLIO_STYLE_2x1 = ['template2x1'] +PORTFOLIO_STYLE_1x2 = ['template1x2'] + 'template1x1': [' '], + 'template1x1a': [' '], + 'template1x2': [' '], + 'template2x1': [' '], + 'template2x2': [' '], + 'templatelist': [' '], + 'template1x1': 't1x1', + 'template1x1a': 't1x1a', + 'template1x2': 't1x2', + 'template2x1': 't2x1', + 'template2x2': 't2x2', + 'templatelist': 'bullet', + + 't1x1': [2, lambda self, x, y: self._show_template1x1(x, y)], + 't1x1a': [2, lambda self, x, y: self._show_template1x1a(x, y)], + 't1x2': [3, lambda self, x, y, z: self._show_template1x2(x, y, z)], + 't2x1': [3, lambda self, x, y, z: self._show_template2x1(x, y, z)], + 't2x2': [5, lambda self, x, y, z, a, b: self._show_template2x2( + x, y, z, a, b)], + 'write': [2, lambda self, x, y: self._write(self, x, y)] + 'template1x1': [_('Title'), 'None'], + 'template1x1a': [_('Title'), 'None'], + 'template1x2': [_('Title'), 'None', 'None'], + 'template2x1': [_('Title'), 'None', 'None'], + 'template2x2': [_('Title'), 'None', 'None', 'None', 'None'], + 'templatelist': [_('Title'), '∙ '], + 'write': [_('text'), 32]} + + 'template1x1a': _('presentation 1x1'), + 'template1x2': _('presentation 1x2'), + 'template2x1': _('presentation 2x1'), + 'template2x2': _('presentation 2x2'), + 'templatelist': _('presentation bulleted list'), + 'template1x1': _( + "presentation template: select Journal object (with description)"), + 'template1x1a': _( + "presentation template: select Journal object (no description)"), + 'template1x2': _("presentation template: select two Journal objects"), + 'template2x1': _("presentation template: select two Journal objects"), + 'template2x2': _("presentation template: select four Journal objects"), + 'templatelist': _("presentation template: list of bullets"), + """ + + def _show_template1x1(self, title, media): + """ title, one image, and description """ + xo = self.tw.calc_position('t1x1')[2] + x = -(self.tw.canvas.width / 2) + xo + y = self.tw.canvas.height / 2 + self.tw.canvas.setxy(x, y, pendown=False) + # save the text size so we can restore it later + save_text_size = self.tw.canvas.textsize + # set title text + self.tw.canvas.settextsize(self.title_height) + self._prim_show(title) + # calculate and set scale for media blocks + myscale = 45 * (self.tw.canvas.height - self.title_height * 2) \ + / self.tw.canvas.height + self._prim_setscale(myscale) + # set body text size + self.tw.canvas.settextsize(self.body_height) + # render media object + # leave some space below the title + y -= int(self.title_height * 2 * self.tw.lead) + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(media) + if self.tw.running_sugar: + x = 0 + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(media.replace('media_', 'descr_')) + # restore text size + self.tw.canvas.settextsize(save_text_size) + + def _show_template2x1(self, title, media1, media2): + """ title, two images (horizontal), two descriptions """ + xo = self.tw.calc_position('t2x1')[2] + x = -(self.tw.canvas.width / 2) + xo + y = self.tw.canvas.height / 2 + self.tw.canvas.setxy(x, y, pendown=False) + # save the text size so we can restore it later + save_text_size = self.tw.canvas.textsize + # set title text + self.tw.canvas.settextsize(self.title_height) + self._prim_show(title) + # calculate and set scale for media blocks + myscale = 45 * (self.tw.canvas.height - self.title_height * 2) / \ + self.tw.canvas.height + self._prim_setscale(myscale) + # set body text size + self.tw.canvas.settextsize(self.body_height) + # render four quadrents + # leave some space below the title + y -= int(self.title_height * 2 * self.tw.lead) + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(media1) + x = 0 + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(media2) + y = -self.title_height + if self.tw.running_sugar: + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(media2.replace('media_', 'descr_')) + x = -(self.tw.canvas.width / 2) + xo + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(media1.replace('media_', 'descr_')) + # restore text size + self.tw.canvas.settextsize(save_text_size) + + def _show_bullets(self, sarray): + """ title and varible number of bullets """ + xo = self.tw.calc_position('bullet')[2] + x = -(self.tw.canvas.width / 2) + xo + y = self.tw.canvas.height / 2 + self.tw.canvas.setxy(x, y, pendown=False) + # save the text size so we can restore it later + save_text_size = self.tw.canvas.textsize + # set title text + self.tw.canvas.settextsize(self.title_height) + self._prim_show(sarray[0]) + # set body text size + self.tw.canvas.settextsize(self.bullet_height) + # leave some space below the title + y -= int(self.title_height * 2 * self.tw.lead) + for s in sarray[1:]: + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(s) + y -= int(self.bullet_height * 2 * self.tw.lead) + # restore text size + self.tw.canvas.settextsize(save_text_size) + + def _show_template1x2(self, title, media1, media2): + """ title, two images (vertical), two desciptions """ + xo = self.tw.calc_position('t1x2')[2] + x = -(self.tw.canvas.width / 2) + xo + y = self.tw.canvas.height / 2 + self.tw.canvas.setxy(x, y, pendown=False) + # save the text size so we can restore it later + save_text_size = self.tw.canvas.textsize + # set title text + self.tw.canvas.settextsize(self.title_height) + self._prim_show(title) + # calculate and set scale for media blocks + myscale = 45 * (self.tw.canvas.height - self.title_height * 2) / \ + self.tw.canvas.height + self._prim_setscale(myscale) + # set body text size + self.tw.canvas.settextsize(self.body_height) + # render four quadrents + # leave some space below the title + y -= int(self.title_height * 2 * self.tw.lead) + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(media1) + if self.tw.running_sugar: + x = 0 + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(media1.replace('media_', 'descr_')) + y = -self.title_height + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(media2.replace('media_', 'descr_')) + x = -(self.tw.canvas.width / 2) + xo + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(media2) + # restore text size + self.tw.canvas.settextsize(save_text_size) + + def _show_template2x2(self, title, media1, media2, media3, media4): + """ title and four images """ + xo = self.tw.calc_position('t2x2')[2] + x = -(self.tw.canvas.width / 2) + xo + y = self.tw.canvas.height / 2 + self.tw.canvas.setxy(x, y, pendown=False) + # save the text size so we can restore it later + save_text_size = self.tw.canvas.textsize + # set title text + self.tw.canvas.settextsize(self.title_height) + self._prim_show(title) + # calculate and set scale for media blocks + myscale = 45 * (self.tw.canvas.height - self.title_height * 2) / \ + self.tw.canvas.height + self._prim_setscale(myscale) + # set body text size + self.tw.canvas.settextsize(self.body_height) + # render four quadrents + # leave some space below the title + y -= int(self.title_height * 2 * self.tw.lead) + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(media1) + x = 0 + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(media2) + y = -self.title_height + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(media4) + x = -(self.tw.canvas.width / 2) + xo + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(media3) + # restore text size + self.tw.canvas.settextsize(save_text_size) + + def _show_template1x1a(self, title, media1): + """ title, one media object """ + xo = self.tw.calc_position('t1x1a')[2] + x = -(self.tw.canvas.width / 2) + xo + y = self.tw.canvas.height / 2 + self.tw.canvas.setxy(x, y, pendown=False) + # save the text size so we can restore it later + save_text_size = self.tw.canvas.textsize + # set title text + self.tw.canvas.settextsize(self.title_height) + self._prim_show(title) + # calculate and set scale for media blocks + myscale = 90 * (self.tw.canvas.height - self.title_height * 2) / \ + self.tw.canvas.height + self._prim_setscale(myscale) + # set body text size + self.tw.canvas.settextsize(self.body_height) + # render media object + # leave some space below the title + y -= int(self.title_height * 2 * self.tw.lead) + self.tw.canvas.setxy(x, y, pendown=False) + self._prim_show(media1) + # restore text size + self.tw.canvas.settextsize(save_text_size) + + def _write(self, string, fsize): + """ Write string at size """ + x = self.tw.canvas.width / 2 + int(self.tw.canvas.xcor) + y = self.tw.canvas.height / 2 - int(self.tw.canvas.ycor) + self.tw.canvas.draw_text(string, x, y - 15, int(fsize), + self.tw.canvas.width) -- cgit v0.9.1