diff options
-rw-r--r-- | TurtleArtActivity.py | 11 | ||||
-rw-r--r-- | tablock.py | 704 | ||||
-rw-r--r-- | tacanvas.py | 2 | ||||
-rw-r--r-- | taconstants.py | 621 | ||||
-rw-r--r-- | talogo.py | 2 | ||||
-rw-r--r-- | taturtle.py | 2 | ||||
-rw-r--r-- | tawindow.py | 15 | ||||
-rwxr-xr-x | turtleart.py | 2 |
8 files changed, 1342 insertions, 17 deletions
diff --git a/TurtleArtActivity.py b/TurtleArtActivity.py index 8adb01a..f2f0722 100644 --- a/TurtleArtActivity.py +++ b/TurtleArtActivity.py @@ -58,12 +58,11 @@ import tarfile import sys import re -from constants import * +from taconstants import * from taexporthtml import save_html from taexportlogo import save_logo -from tautils import * -import tawindow -import talogo +from tautils import data_to_file, data_to_string, data_from_string +from tawindow import TurtleArtWindow SERVICE = 'org.laptop.TurtleArtActivity' IFACE = SERVICE @@ -940,8 +939,8 @@ class TurtleArtActivity(activity.Activity): """ def _setup_canvas(self, canvas, lang): bundle_path = activity.get_bundle_path() - self.tw = tawindow.TurtleArtWindow(canvas, bundle_path, lang, self, - profile.get_color().to_string()) + self.tw = TurtleArtWindow(canvas, bundle_path, lang, self, + profile.get_color().to_string()) self.tw.activity = self self.tw.window.grab_focus() path = os.path.join(os.environ['SUGAR_ACTIVITY_ROOT'], 'data') diff --git a/tablock.py b/tablock.py new file mode 100644 index 0000000..e740c9e --- /dev/null +++ b/tablock.py @@ -0,0 +1,704 @@ +# -*- coding: utf-8 -*- +#Copyright (c) 2010 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. + +from taconstants import * +from sprite_factory import SVG, svg_str_to_pixbuf +import sprites +from gettext import gettext as _ + +# +# A class for the list of blocks and everything they share in common +# +class Blocks: + def __init__(self, font_scale_factor = 1): + self.list = [] + self.font_scale_factor = font_scale_factor + + def get_block(self, i): + if i < 0 or i > len(self.list)-1: + return(None) + else: + return(self.list[i]) + + def length_of_list(self): + return(len(self.list)) + + def append_to_list(self,block): + self.list.append(block) + + def remove_from_list(self, block): + if block in self.list: + self.list.remove(block) + + def print_list(self, block_type=None): + for i, block in enumerate(self.list): + if block_type is None or block_type == block.type: + print "%d: %s" % (i, block.name) + + # + # sprite utilities + # + def spr_to_block(self, spr): + for b in self.list: + if spr == b.spr: + return b + return None + +# +# A class for the individual blocks +# +class Block: + # + # TODO: + # block data should be stored in block, not in block.spr.label + # Logo code + # HTML code + # debug code + # etc. + def __init__(self, block_list, sprite_list, name, x, y, type='block', + values=[], scale=BLOCK_SCALE, colors=["#00FF00","#00A000"]): + self.spr = None + self.shapes = [] + self.name = name + self.colors = colors + self.scale = scale + self.docks = None + self.connections = None + self.values = [] + self.primitive = None + self.type = type + self._dx = 0 + self._ei = 0 + self._ex = 0 + self._ey = 0 + self._font_size = [6.0, 4.5] + self._left = 2 + self._right = 2 + + if OLD_NAMES.has_key(self.name): + self.name = OLD_NAMES[self.name] + + for i in range(len(self._font_size)): + self._font_size[i] *= self.scale*block_list.font_scale_factor + + for v in (values): + self.values.append(v) + + self._new_block_from_factory(sprite_list, x, y) + + if PRIMITIVES.has_key(name): + self.primitive = PRIMITIVES[self.name] + + block_list.append_to_list(self) + + # We need to resize some blocks on the fly. + def resize(self): + # make sure the label fits + lw = self.spr.label_width() + lwh = self.spr.label_area_dimensions() + self._dx = (lw-lwh[0]) + if self._dx < 0: + self._dx = 0 + self._make_block(self.svg) + self.spr.set_shape(self.shapes[0]) + + # We may want to rescale blocks as well. + def rescale(self, scale): + for i in range(len(self._font_size)): + self._font_size[i] /= self.scale + self.scale = scale + for i in range(len(self._font_size)): + self._font_size[i] *= self.scale + self._make_block(self.svg) + self.spr.set_shape(self.shapes[0]) + + # We may want to add "innies" + def add_arg(self): + h = self.svg.get_height() + self._ei += 1 + self.svg.set_show(True) + self._make_block(self.svg) + self.spr.set_shape(self.shapes[0]) + return self.svg.get_height()-h + + # We may want to grow a block vertically. + def expand_in_y(self, dy): + self._ey += dy + self.svg.set_hide(True) + self.svg.set_show(True) + self._make_block(self.svg) + self.spr.set_shape(self.shapes[0]) + + # We may want to grow a block horizontally. + def expand_in_x(self, dx): + self._ex += dx + self.svg.set_hide(True) + self.svg.set_show(True) + self._make_block(self.svg) + self.spr.set_shape(self.shapes[0]) + + def reset_x(self): + dx = -self._ex + self._ex = 0 + self.svg.set_hide(False) + self.svg.set_show(True) + self._make_block(self.svg) + self.spr.set_shape(self.shapes[0]) + return dx + + def reset_y(self): + dy = -self._ey + self._ey = 0 + self.svg.set_hide(False) + self.svg.set_show(True) + self._make_block(self.svg) + self.spr.set_shape(self.shapes[0]) + return dy + + def get_expand_x_y(self): + return (self._ex, self._ey) + + def _new_block_from_factory(self, sprite_list, x, y): + self.svg = SVG() + self.svg.set_scale(self.scale) + self.svg.set_gradiant(True) + self.svg.set_innie([False]) + self.svg.set_outie(False) + self.svg.set_tab(True) + self.svg.set_slot(True) + + if self.name in EXPANDABLE and self.type == 'block': + self.svg.set_show(True) + + self._make_block(self.svg) + self.spr = sprites.Sprite(sprite_list, x, y, self.shapes[0]) + + self.spr.set_margins(self._left, self.svg.get_slot_depth(), self._right, + self.svg.get_slot_depth()*2) + + if self.name in CONTENT_BLOCKS and len(self.values) > 0: + for i, v in enumerate(self.values): + self._set_labels(i, str(v)) + elif BLOCK_NAMES.has_key(self.name): + for i, n in enumerate(BLOCK_NAMES[self.name]): + self._set_labels(i, n) + + # Make sure the labels fit. + self.resize() + + def _set_labels(self, i, label): + if i == 1: # top + self.spr.set_label_attributes(int(self._font_size[1]+0.5), True, + "right", "top", i) + elif i == 2: # bottom + self.spr.set_label_attributes(int(self._font_size[1]+0.5), True, + "right", "bottom", i) + else: + self.spr.set_label_attributes(int(self._font_size[0]+0.5), True, + "center", "middle", i) + self.spr.set_label(label, i) + + def _make_block(self, svg): + self._set_colors(svg) + self.svg.set_stroke_width(STANDARD_STROKE_WIDTH) + self.svg.clear_docks() + self.shapes = [] + if self.name in BASIC_STYLE: + self._make_basic_style(svg) + elif self.name in BASIC_STYLE_HEAD: + self._make_basic_style_head(svg) + elif self.name in BASIC_STYLE_HEAD_1ARG: + self._make_basic_style_head_1arg(svg) + elif self.name in BASIC_STYLE_TAIL: + self._make_basic_style_tail(svg) + elif self.name in BASIC_STYLE_1ARG: + self._make_basic_style_1arg(svg) + elif self.name in BASIC_STYLE_2ARG: + self._make_basic_style_2arg(svg) + elif self.name in BULLET_STYLE: + self._make_basic_style_var_arg(svg) + elif self.name in BOX_STYLE: + self._make_box_style(svg) + elif self.name in BOX_STYLE_MEDIA: + self._make_media_style(svg) + elif self.name in NUMBER_STYLE: + self._make_number_style(svg) + elif self.name in NUMBER_STYLE_BLOCK: + self._make_number_style_block(svg) + elif self.name in NUMBER_STYLE_1ARG: + self._make_number_style_1arg(svg) + elif self.name in NUMBER_STYLE_1STRARG: + self._make_number_style_1strarg(svg) + elif self.name in NUMBER_STYLE_PORCH: + self._make_number_style_porch(svg) + elif self.name in COMPARE_STYLE: + self._make_compare_style(svg) + elif self.name in BOOLEAN_STYLE: + self._make_boolean_style(svg) + elif self.name in NOT_STYLE: + self._make_not_style(svg) + elif self.name in FLOW_STYLE: + self._make_flow_style(svg) + elif self.name in FLOW_STYLE_1ARG: + self._make_flow_style_1arg(svg) + elif self.name in FLOW_STYLE_BOOLEAN: + self._make_flow_style_boolean(svg) + elif self.name in FLOW_STYLE_ELSE: + self._make_flow_style_else(svg) + elif self.name in PORTFOLIO_STYLE_2x2: + self._make_portfolio_style_2x2(svg) + elif self.name in PORTFOLIO_STYLE_2x1: + self._make_portfolio_style_2x1(svg) + elif self.name in PORTFOLIO_STYLE_1x1: + self._make_portfolio_style_1x1(svg) + elif self.name in PORTFOLIO_STYLE_1x2: + self._make_portfolio_style_1x2(svg) + else: + self._make_basic_style(svg) + print ">>>>> I don't know how to create a %s block" % (self.name) + + def _set_colors(self, svg): + if BOX_COLORS.has_key(self.name): + self.colors = BOX_COLORS[self.name] + else: + for p in range(len(PALETTES)): + if self.name in PALETTES[p]: + self.colors = COLORS[p] + self.svg.set_colors(self.colors) + + def _make_basic_style(self, svg): + self.svg.expand(self._dx+self._ex, self._ey) + self._make_basic_block(svg) + self.docks = [['flow',True,self.svg.docks[0][0],self.svg.docks[0][1]], + ['flow',False,self.svg.docks[1][0],self.svg.docks[1][1]]] + self._left, self._right = 2, 2 + + def _make_basic_style_head(self, svg): + self.svg.expand(10+self._dx+self._ex, self._ey) + self.svg.set_slot(False) + self.svg.set_cap(True) + self._make_basic_block(svg) + self.docks = [['start', True, 0, 0], + ['flow', False, self.svg.docks[0][0], + self.svg.docks[0][1]]] + self._left, self._right = 2, 2 + + def _make_basic_style_head_1arg(self, svg): + self.svg.expand(10+self._dx+self._ex, self._ey) + self.svg.set_innie([True]) + self.svg.set_slot(False) + self.svg.set_cap(True) + self._make_basic_block(svg) + self.docks = [['start', True, 0, 0], + ['string', False, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['flow', False, self.svg.docks[1][0], + self.svg.docks[1][1]]] + self._left, self._right = 2, self.svg.get_innie_width()*1.5 + + def _make_basic_style_tail(self, svg): + self.svg.expand(10+self._dx+self._ex, self._ey) + self.svg.set_tab(False) + self._make_basic_block(svg) + self.docks = [['flow', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['unavailable', False, 0, 0]] + + def _make_basic_style_1arg(self, svg): + self.svg.expand(10+self._dx+self._ex, self._ey) + self.svg.set_innie([True]) + self._make_basic_block(svg) + self.docks = [['flow', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['number', False, self.svg.docks[1][0], + self.svg.docks[1][1]], + ['flow', False, self.svg.docks[2][0], + self.svg.docks[2][1]]] + self._left, self._right = 2, self.svg.get_innie_width()*1.5 + + def _make_basic_style_2arg(self, svg): + self.svg.expand(10+self._dx+self._ex, self._ey) + self.svg.set_innie([True,True]) + self._make_basic_block(svg) + self.docks = [['flow', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['number', False, self.svg.docks[1][0], + self.svg.docks[1][1]], + ['number', False, self.svg.docks[2][0], + self.svg.docks[2][1]], + ['flow', False, self.svg.docks[3][0], + self.svg.docks[3][1]]] + self._left, self._right = 2, self.svg.get_innie_width()*1.5 + + def _make_basic_style_var_arg(self, svg): + self.svg.expand(10+self._dx+self._ex, self._ey) + innie = [True, True] + for i in range(self._ei): + innie.append(True) + self.svg.set_innie(innie) + self._make_basic_block(svg) + self.docks = [['flow', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['string', False, self.svg.docks[1][0], + self.svg.docks[1][1]], + ['string', False, self.svg.docks[2][0], + self.svg.docks[2][1], '[']] + for i in range(self._ei): + self.docks.append(['string', False, self.svg.docks[i+3][0], + self.svg.docks[i+3][1]]) + self.docks.append(['flow', False, self.svg.docks[self._ei+3][0], + self.svg.docks[self._ei+3][1], ']']) + self._left, self._right = 2, self.svg.get_innie_width()*1.5 + + def _make_box_style(self, svg): + self.svg.expand(60+self._dx+self._ex, self._ey) + self._make_basic_box(svg) + self.docks = [['number', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['unavailable', False, 0, 0]] + self._left, self._right = self.svg.docks[1][0], 1 + + def _make_media_style(self, svg): + self.svg.expand(40+self._dx+self._ex, 10+self._ey) + self._make_basic_box(svg) + self.docks = [['number', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['unavailable', False, 0, 0]] + self._left, self._right = self.svg.docks[1][0], 1 + + def _make_number_style(self, svg): + self.svg.expand(self._dx+self._ex, self._ey) + self.svg.set_innie([True,True]) + self.svg.set_outie(True) + self.svg.set_tab(False) + self.svg.set_slot(False) + self._make_basic_block(svg) + """ + NOTE: The "outie" is added last, so the dock order in the NUMBER_STYLE + needs to be modified. + """ + self.docks = [['number', True, self.svg.docks[2][0], + self.svg.docks[2][1]], + ['number', False, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['number', False, self.svg.docks[1][0], + self.svg.docks[1][1]]] + self._left = self.svg.docks[2][0] + self._right = self.svg.get_innie_width()*1.5 + + def _make_number_style_block(self, svg): + self.svg.expand(self._dx+self._ex, self._ey) + self.svg.set_innie([True,True]) + self.svg.set_outie(True) + self.svg.set_tab(False) + self.svg.set_slot(False) + self._make_basic_block(svg) + self.docks = [['number', True, self.svg.docks[2][0], + self.svg.docks[2][1], '('], + ['number', False, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['number', False, self.svg.docks[1][0], + self.svg.docks[1][1]], + ['unavailable', False, 0, 0, ')']] + self._left = self.svg.docks[2][0] + self._right = self.svg.get_innie_width()*1.5 + + def _make_number_style_1arg(self, svg): + self.svg.expand(self._dx+self._ex, self._ey) + self.svg.set_innie([True]) + self.svg.set_outie(True) + self.svg.set_tab(False) + self.svg.set_slot(False) + self._make_basic_block(svg) + self.docks = [['number', True, self.svg.docks[1][0], + self.svg.docks[1][1]], + ['number', False, self.svg.docks[0][0], + self.svg.docks[0][1]]] + self._left, self._right = self.svg.docks[1][0], self.svg.docks[1][0] + + def _make_number_style_1strarg(self, svg): + self.svg.expand(self._dx+self._ex, self._ey) + self.svg.set_innie([True]) + self.svg.set_outie(True) + self.svg.set_tab(False) + self.svg.set_slot(False) + self._make_basic_block(svg) + self.docks = [['number', True, self.svg.docks[1][0], + self.svg.docks[1][1]], + ['string', False, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['unavailable', False, 0, 0]] + self._left, self._right = self.svg.docks[1][0], self.svg.docks[1][0] + + def _make_number_style_porch(self, svg): + self.svg.expand(self._dx+self._ex, self._ey) + self.svg.set_innie([True,True]) + self.svg.set_outie(True) + self.svg.set_tab(False) + self.svg.set_slot(False) + self.svg.set_porch(True) + self._make_basic_block(svg) + self.docks = [['number', True, self.svg.docks[2][0], + self.svg.docks[2][1]], + ['number', False, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['number', False, self.svg.docks[1][0], + self.svg.docks[1][1]]] + self._left = self.svg.docks[2][0] + self._right = self.svg.get_width()-self.svg.docks[0][0] + + def _make_compare_style(self, svg): + self.svg.expand(10+self._dx+self._ex, self._ey) + self._make_boolean_compare(svg) + self.docks = [['bool', True, self.svg.docks[0][0], + self.svg.docks[0][1], '('], + ['number', False, self.svg.docks[1][0], + self.svg.docks[1][1]], + ['number', False, self.svg.docks[2][0], + self.svg.docks[2][1]], + ['unavailable', False, 0, 0, ')']] + self._left, self._right = self.svg.get_width()-self.svg.docks[2][0], 0 + + def _make_boolean_style(self, svg): + self.svg.expand(10+self._dx+self._ex, self._ey) + self._make_boolean_and_or(svg) + self.docks = [['bool', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['bool', False, self.svg.docks[1][0], + self.svg.docks[1][1]], + ['bool', False, self.svg.docks[2][0], + self.svg.docks[2][1]]] + self._left, self._right = self.svg.get_width()-self.svg.docks[1][0], 0 + + def _make_not_style(self, svg): + self.svg.expand(15+self._dx+self._ex, self._ey) + self._make_boolean_not(svg) + self.docks = [['bool', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['bool', False, self.svg.docks[1][0], + self.svg.docks[1][1]]] + self._right = self.svg.get_width()-self.svg.docks[1][0] + self._left = self._right + + def _make_flow_style(self, svg): + self.svg.expand(10+self._dx+self._ex, self._ey) + self.svg.set_slot(True) + self.svg.set_tab(False) + self._make_basic_flow(svg) + # This is an ugly hack. + if self.name == 'forever': + self.docks = [['flow', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['flow', False, self.svg.docks[1][0], + self.svg.docks[1][1], '['], + ['unavailable', False, 0, 0, ']']] + else: + self.docks = [['flow', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['flow', False, self.svg.docks[1][0], + self.svg.docks[1][1]]] + self._left, self._right = 0, self.svg.get_width()-self.svg.docks[1][0] + + def _make_flow_style_1arg(self, svg): + self.svg.expand(self._dx+self._ex, self._ey) + self.svg.set_slot(True) + self.svg.set_tab(True) + self.svg.set_innie([True]) + self._make_basic_flow(svg) + self.docks = [['flow', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['number', False, self.svg.docks[1][0], + self.svg.docks[1][1]], + ['flow', False, self.svg.docks[2][0], + self.svg.docks[2][1], '['], + ['flow', False, self.svg.docks[3][0], + self.svg.docks[3][1], ']']] + self._left = 2 + self._right = self.svg.get_width()-self.svg.docks[1][0]+ \ + self.svg.get_innie_width()*1.5 + + def _make_flow_style_boolean(self, svg): + self.svg.expand(self._dx+self._ex, self._ey) + self.svg.set_slot(True) + self.svg.set_tab(True) + self.svg.set_boolean(True) + self._make_basic_flow(svg) + self.docks = [['flow', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['bool', False, self.svg.docks[1][0], + self.svg.docks[1][1]], + ['flow', False, self.svg.docks[2][0], + self.svg.docks[2][1], '['], + ['flow', False, self.svg.docks[3][0], + self.svg.docks[3][1], ']']] + self._left, self._right = 2, self.svg.get_width()-self.svg.docks[1][0] + + def _make_flow_style_else(self, svg): + self.svg.expand(self._dx+self._ex, self._ey) + self.svg.set_slot(True) + self.svg.set_tab(True) + self.svg.set_else(True) + self.svg.set_boolean(True) + self._make_basic_flow(svg) + self.docks = [['flow', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['bool', False, self.svg.docks[1][0], + self.svg.docks[1][1]], + ['flow', False, self.svg.docks[3][0], + self.svg.docks[3][1], '['], + ['flow', False, self.svg.docks[2][0], + self.svg.docks[2][1], ']['], + ['flow', False, self.svg.docks[4][0], + self.svg.docks[4][1], ']']] + self._left, self._right = 2, self.svg.get_width()-self.svg.docks[1][0] + + def _make_portfolio_style_2x2(self, svg): + self.svg.expand(30+self._dx+self._ex, 10+self._ey) + self.svg.set_slot(True) + self.svg.set_tab(True) + self.svg.set_innie([True, True, False, True]) + self._make_portfolio(svg) + self.docks = [['flow', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['string', False, self.svg.docks[6][0], + self.svg.docks[6][1]], + ['media', False, self.svg.docks[5][0], + self.svg.docks[5][1]], + ['media', False, self.svg.docks[1][0], + self.svg.docks[1][1]], + ['media', False, self.svg.docks[4][0], + self.svg.docks[4][1]], + ['media', False, self.svg.docks[2][0], + self.svg.docks[2][1]], + ['flow', False, self.svg.docks[3][0], + self.svg.docks[3][1]]] + self._left, self._right = 2, self.svg.get_width()-2 + + def _make_portfolio_style_2x1(self, svg): + self.svg.expand(30+self._dx+self._ex, 10+self._ey) + self.svg.set_slot(True) + self.svg.set_tab(True) + self.svg.set_innie([True, True]) + self._make_portfolio(svg) + self.docks = [['flow', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['string', False, self.svg.docks[4][0], + self.svg.docks[4][1]], + ['media', False, self.svg.docks[3][0], + self.svg.docks[3][1]], + ['media', False, self.svg.docks[1][0], + self.svg.docks[1][1]], + ['flow', False, self.svg.docks[2][0], + self.svg.docks[2][1]]] + self._left, self._right = 2, self.svg.get_width()-2 + + def _make_portfolio_style_1x2(self, svg): + self.svg.expand(30+self._dx+self._ex, 15+self._ey) + self.svg.set_slot(True) + self.svg.set_tab(True) + self.svg.set_innie([True, True, False, True]) + self.svg.set_draw_innies(False) + self._make_portfolio(svg) + self.docks = [['flow', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['string', False, self.svg.docks[4][0], + self.svg.docks[4][1]], + ['media', False, self.svg.docks[3][0], + self.svg.docks[3][1]], + ['media', False, self.svg.docks[2][0], + self.svg.docks[2][1]], + ['flow', False, self.svg.docks[1][0], + self.svg.docks[1][1]]] + self._left, self._right = 2, self.svg.get_width()-2 + + + def _make_portfolio_style_1x1(self, svg): + self.svg.expand(30+self._dx+self._ex, 15+self._ey) + self.svg.set_slot(True) + self.svg.set_tab(True) + self.svg.set_innie([True, True]) + self.svg.set_draw_innies(False) + self._make_portfolio(svg) + self.docks = [['flow', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['string', False, self.svg.docks[3][0], + self.svg.docks[3][1]], + ['media', False, self.svg.docks[2][0], + self.svg.docks[2][1]], + ['flow', False, self.svg.docks[1][0], + self.svg.docks[1][1]]] + self._left, self._right = 2, self.svg.get_width()-2 + + def _make_basic_block(self, svg): + self.shapes.append(svg_str_to_pixbuf(self.svg.basic_block())) + self.width = self.svg.get_width() + self.height = self.svg.get_height() + self.svg.set_stroke_width(SELECTED_STROKE_WIDTH) + self.svg.set_stroke_color(SELECTED_COLOR) + self.shapes.append(svg_str_to_pixbuf(self.svg.basic_block())) + + def _make_basic_box(self, svg): + self.shapes.append(svg_str_to_pixbuf(self.svg.basic_box())) + self.width = self.svg.get_width() + self.height = self.svg.get_height() + self.svg.set_stroke_width(SELECTED_STROKE_WIDTH) + self.svg.set_stroke_color(SELECTED_COLOR) + self.shapes.append(svg_str_to_pixbuf(self.svg.basic_box())) + + def _make_portfolio(self, svg): + self.shapes.append(svg_str_to_pixbuf(self.svg.portfolio())) + self.width = self.svg.get_width() + self.height = self.svg.get_height() + self.svg.set_stroke_width(SELECTED_STROKE_WIDTH) + self.svg.set_stroke_color(SELECTED_COLOR) + self.shapes.append(svg_str_to_pixbuf(self.svg.portfolio())) + + def _make_basic_flow(self, svg): + self.shapes.append(svg_str_to_pixbuf(self.svg.basic_flow())) + self.width = self.svg.get_width() + self.height = self.svg.get_height() + self.svg.set_stroke_width(SELECTED_STROKE_WIDTH) + self.svg.set_stroke_color(SELECTED_COLOR) + self.shapes.append(svg_str_to_pixbuf(self.svg.basic_flow())) + + def _make_boolean_compare(self, svg): + self.shapes.append(svg_str_to_pixbuf(self.svg.boolean_compare())) + self.width = self.svg.get_width() + self.height = self.svg.get_height() + self.svg.set_stroke_width(SELECTED_STROKE_WIDTH) + self.svg.set_stroke_color(SELECTED_COLOR) + self.shapes.append(svg_str_to_pixbuf(self.svg.boolean_compare())) + + def _make_boolean_and_or(self, svg): + self.shapes.append(svg_str_to_pixbuf(self.svg.boolean_and_or())) + self.width = self.svg.get_width() + self.height = self.svg.get_height() + self.svg.set_stroke_width(SELECTED_STROKE_WIDTH) + self.svg.set_stroke_color(SELECTED_COLOR) + self.shapes.append(svg_str_to_pixbuf(self.svg.boolean_and_or())) + + def _make_boolean_not(self, svg): + self.shapes.append(svg_str_to_pixbuf(self.svg.boolean_not())) + self.width = self.svg.get_width() + self.height = self.svg.get_height() + self.svg.set_stroke_width(SELECTED_STROKE_WIDTH) + self.svg.set_stroke_color(SELECTED_COLOR) + self.shapes.append(svg_str_to_pixbuf(self.svg.boolean_not())) diff --git a/tacanvas.py b/tacanvas.py index 362cc7f..23c512b 100644 --- a/tacanvas.py +++ b/tacanvas.py @@ -24,7 +24,7 @@ from math import sin, cos, pi from sprites import Sprite import pango -from constants import * +from taconstants import * def wrap100(n): n = int(n) diff --git a/taconstants.py b/taconstants.py new file mode 100644 index 0000000..f5ab419 --- /dev/null +++ b/taconstants.py @@ -0,0 +1,621 @@ +# -*- coding: utf-8 -*- +#Copyright (c) 2010, Walter Bender + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +from gettext import gettext as _ + +# +# sprite layers +# + +HIDE_LAYER = 100 +CANVAS_LAYER = 500 +OVERLAY_LAYER = 525 +TURTLE_LAYER = 550 +BLOCK_LAYER = 600 +CATEGORY_LAYER = 700 +TAB_LAYER = 710 +STATUS_LAYER = 900 +TOP_LAYER = 1000 + +# +# block palette categories +# + +PALETTE_NAMES = ['turtle', 'pen', 'colors', 'numbers', 'flow', 'blocks', + 'extras', 'portfolio', 'trash'] + +PALETTES = [['forward', 'back', 'clean', 'left', 'right', 'show', + 'seth', 'setxy', 'heading', 'xcor', 'ycor', 'setscale', + 'arc', 'scale'], + ['penup','pendown', 'setpensize', 'fillscreen', 'pensize', + 'settextsize', 'setcolor', 'setshade', 'textsize', 'color', + 'shade'], + [ 'red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'purple'], + ['plus2', 'minus2', 'product2', + 'division2', 'identity2', 'remainder2', 'sqrt', 'random', + 'number', 'greater2', 'less2', 'equal2', 'not', 'and2', 'or2'], + ['wait', 'forever', 'repeat', 'if', 'ifelse', 'hspace', + 'vspace', 'stopstack'], + ['hat1', 'stack1', 'hat', 'hat2', 'stack2', 'stack', + 'storeinbox1', 'storeinbox2', 'string', 'box1', 'box2', 'box', + 'storein', 'start'], + ['kbinput', 'push', 'printheap', 'keyboard', 'pop', 'clearheap', + 'myfunc', 'nop', 'leftpos', 'toppos', 'width', 'rightpos', + 'bottompos', 'height', 'addturtle', 'print'], + ['journal', 'audio', 'description', 'templatelist', 'template1x1a', + 'template1x1', 'template1x2', 'template2x1', 'template2x2', + 'hideblocks', 'showblocks'], + ['restore']] + +# +# block style attributes +# + +COLORS = [["#00FF00","#00A000"], ["#00FFFF","#00A0A0"], ["#00FFFF","#00A0A0"], + ["#FF00FF","#A000A0"], ["#FFC000","#A08000"], ["#FFFF00","#A0A000"], + ["#FF0000","#A00000"], ["#0000FF","#0000FF"], ["#FFFF00","#A0A000"]] + +BOX_COLORS = {'red':["#FF0000","#A00000"],'orange':["#FFD000","#AA8000"], + 'yellow':["#FFFF00","#A0A000"],'green':["#00FF00","#008000"], + 'cyan':["#00FFFF","#00A0A0"],'blue':["#0000FF","#000080"], + 'purple':["#FF00FF","#A000A0"]} + +PALETTE_HEIGHT = 120 +PALETTE_WIDTH = 180 +SELECTOR_WIDTH = 55 +ICON_SIZE = 55 +SELECTED_COLOR = "#0000FF" +SELECTED_STROKE_WIDTH = 1.5 +STANDARD_STROKE_WIDTH = 1.0 +THUMB_W = 80 +THUMB_H = 60 +PYTHON_X = 17 +PYTHON_Y = 8 +MEDIA_X = 37 +MEDIA_Y = 6 +TEMPLATE_X = 24 +TEMPLATE_Y = 18 +PIXBUF_X = 17 +PIXBUF_Y = 2 +BLOCK_SCALE = 2.0 +PALETTE_DEFAULT_SCALE = 1.5 +PALETTE_SCALE = {'template2x2':1.0, 'template1x2':1.0} + +# +# block style definitions +# +BASIC_STYLE_HEAD = ['start', 'hat1', 'hat2', 'restore'] +BASIC_STYLE_HEAD_1ARG = ['hat'] +BASIC_STYLE_TAIL = ['stopstack'] +BASIC_STYLE = ['clean', 'penup', 'pendown', 'stack1', 'stack2', 'vspace', + 'hideblocks', 'showblocks', 'clearheap', 'printheap', 'kbinput'] +BASIC_STYLE_1ARG = ['forward', 'back', 'left', 'right', 'seth', 'show', + 'setscale', 'setpensize', 'setcolor', 'setshade', 'print', + 'settextsize', 'settextcolor', 'print', 'wait', 'storeinbox1', + 'storeinbox2', 'wait', 'stack', 'push', 'nop', 'addturtle'] +BASIC_STYLE_2ARG = ['arc', 'setxy', 'fillscreen', 'storein'] +BOX_STYLE = ['number', 'xcor', 'ycor', 'heading', 'pensize', 'color', 'shade', + 'textcolor', 'textsize', 'box1', 'box2', 'string', 'leftpos', 'scale', + 'toppos', 'rightpos', 'bottompos', 'width', 'height', 'pop', 'keyboard', + 'red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'purple'] +BOX_STYLE_MEDIA = ['description', 'audio', 'journal'] +NUMBER_STYLE = ['plus2', 'product2', 'myfunc'] +NUMBER_STYLE_BLOCK = ['random'] +NUMBER_STYLE_PORCH = ['minus2', 'division2', 'remainder2'] +NUMBER_STYLE_1ARG = ['sqrt', 'identity2'] +NUMBER_STYLE_1STRARG = ['box'] +COMPARE_STYLE = ['greater2', 'less2', 'equal2'] +BOOLEAN_STYLE = ['and2', 'or2'] +NOT_STYLE = ['not'] +FLOW_STYLE = ['forever', 'hspace'] +FLOW_STYLE_1ARG = ['repeat'] +FLOW_STYLE_BOOLEAN = ['if'] +FLOW_STYLE_ELSE = ['ifelse'] +PORTFOLIO_STYLE_2x2 = ['template2x2'] +BULLET_STYLE = ['templatelist'] +PORTFOLIO_STYLE_1x1 = ['template1x1', 'template1x1a'] +PORTFOLIO_STYLE_2x1 = ['template2x1'] +PORTFOLIO_STYLE_1x2 = ['template1x2'] + + +# +# Macros (groups of blocks) +# +MACROS = { + 'kbinput':[[0, 'forever', 0, 0, [None, 1, None]], + [1, 'kbinput', 0, 0, [0, 2]], + [2, 'vspace', 0, 0, [1, 3]], + [3, 'if', 0, 0, [2, 4, 7, 8]], + [4, 'greater2', 0, 0, [3, 5, 6, None]], + [5, 'keyboard', 0, 0, [4, None]], + [6, ['number', '0'], 0, 0, [4, None]], + [7, 'stopstack', 0, 0, [3, None]], + [8, 'vspace', 0, 0, [3, 9]], + [9, 'wait', 0, 0, [8, 10, None]], + [10, ['number', '1'], 0, 0, [9, None]]] + } + +# +# blocks that are expandable +# +EXPANDABLE = ['vspace', 'hspace', 'templatelist', 'identity2'] + +# +# Old block styles that need dock adjustments +# +OLD_DOCK = ['and', 'or'] + +# +# blocks that contain media +# +CONTENT_BLOCKS = ['number', 'string', 'description', 'audio', 'journal'] + +# +# block name dictionary used for labels +# +BLOCK_NAMES = { + 'addturtle':[_('turtle')], + 'and2':[_('and')], + 'arc':[_('arc'),_('angle'),_('radius')], + 'audio':[' '], + 'back':[_('back')], + 'blue':[_('blue')], + 'bottompos':[_('bottom')], + 'box':[_('box')], + 'box1':[_('box 1')], + 'box2':[_('box 2')], + 'clean':[_('clean')], + 'clearheap':[_('empty heap')], + 'color':[_('color')], + 'cyan':[_('cyan')], + 'division2':['/'], + 'equal2':['='], + 'fillscreen':[_('fill screen'),_('color'),_('shade')], + 'forever':[_('forever')], + 'forward':[_('forward')], + 'greater2':[">"], + 'green':[_('green')], + 'hat':[_('action')], + 'hat1':[_('action 1')], + 'hat2':[_('action 2')], + 'heading':[_('heading')], + 'height':[_('height')], + 'hideblocks':[_('hide blocks')], + 'hspace':[' '], + 'identity2':['←'], + 'if':[' ',_('if'),_('then')], + 'ifelse':[' ',_('if'),_('then else')], + 'journal':[' '], + 'kbinput':[_('query keyboard')], + 'keyboard':[_('keyboard')], + 'left':[_('left')], + 'leftpos':[_('left')], + 'less2':['<'], + 'minus2':['–'], + 'myfunc':[_('Python'),_('code'),_('value')], + 'nop':[_(' ')], + 'not':[_('not')], + 'number':['100'], + 'orange':[_('orange')], + 'or2':[_('or')], + 'pendown':[_('pen down')], + 'pensize':[_('pen size')], + 'penup':[_('pen up')], + 'plus2':['+'], + 'pop':[_('pop')], + 'printheap':[_('show heap')], + 'print':[_('print')], + 'product2':['×'], + 'purple':[_('purple')], + 'push':[_('push')], + 'random':[_('random'),_('min'),_('max')], + 'red':[_('red')], + 'remainder2':[_('mod')], + 'repeat':[' ',_('repeat')], + 'restore':[_('restore')], + 'rightpos':[_('right')], + 'right':[_('right')], + 'scale':[_('scale')], + 'setcolor':[_('set color')], + 'seth':[_('set heading')], + 'setpensize':[_('set pen size')], + 'setscale':[_('set scale')], + 'setshade':[_('set shade')], + 'settextsize':[_('set text size')], + 'setxy':[_('set xy'),_('x'),_('y')], + 'shade':[_('shade')], + 'show':[_('show')], + 'showblocks':[_('show blocks')], + 'sqrt':['√'], + 'stack':[_('action')], + 'stack1':[_('action 1')], + 'stack2':[_('action 2')], + 'start':[_('start')], + 'stopstack':[_('stop action')], + 'storein':[_('store in')], + 'storeinbox1':[_('store in box 1')], + 'storeinbox2':[_('store in box 2')], + 'string':[_('text')], + 'template1x1':[' '], + 'template1x1a':[' '], + 'template1x2':[' '], + 'template2x1':[' '], + 'template2x2':[' '], + 'templatelist':[' '], + 'textsize':[_('text size')], + 'toppos':[_('top')], + 'turtle':[_('turtle')], + 'vspace':[' '], + 'wait':[_('wait')], + 'width':[_('width')], + 'xcor':[_('xcor')], + 'ycor':[_('ycor')], + 'yellow':[_('yellow')]} + +# +# Logo primitives +# + +PRIMITIVES = { + 'addturtle':'turtle', + 'and2':'and', + 'arc':'arc', + 'back':'back', + 'blue':'blue', + 'bottompos':'bpos', + 'box1':'box1', + 'box2':'box2', + 'box':'box', + 'clean':'clean', + 'clearheap':'clearheap', + 'color':'color', + 'cyan':'cyan', + 'division2':'division', + 'equal2':'equal?', + 'fillscreen':'fillscreen', + 'forever':'forever', + 'forward':'forward', + 'greater2':'greater?', + 'green':'green', + 'hat':'nop3', + 'hat1':'nop1', + 'hat2':'nop2', + 'heading':'heading', + 'height':'vres', + 'hideblocks':'hideblocks', + 'hspace':'nop', + 'identity2':'id', + 'if':'if', + 'ifelse':'ifelse', + 'kbinput':'kbinput', + 'keyboard':'keyboard', + 'left':'left', + 'leftpos':'lpos', + 'less2':'less?', + 'templatelist':'bullet', + 'minus2':'minus', + 'myfunc':'myfunc', + 'nop':'userdefined', + 'not':'not', + 'orange':'orange', + 'or2':'or', + 'pendown':'pendown', + 'pensize':'pensize', + 'penup':'penup', + 'plus2':'plus', + 'pop':'pop', + 'printheap':'printheap', + 'print':'print', + 'product2':'product', + 'purple':'purple', + 'push':'push', + 'random':'random', + 'red':'red', + 'remainder2':'mod', + 'repeat':'repeat', + 'rightpos':'rpos', + 'right':'right', + 'scale':'scale', + 'setcolor':'setcolor', + 'seth':'seth', + 'setpensize':'setpensize', + 'setscale':'setscale', + 'setshade':'setshade', + 'settextsize':'settextsize', + 'settextcolor':'settextcolor', + 'setxy':'setxy', + 'shade':'shade', + 'show':'show', + 'showblocks':'showblocks', + 'sqrt':'sqrt', + 'stack':'stack', + 'stack1':'stack1', + 'stack2':'stack2', + 'start':'start', + 'stopstack':'stopstack', + 'storein':'storeinbox', + 'storeinbox1':'storeinbox1', + 'storeinbox2':'storeinbox2', + 'template1x1':'t1x1', + 'template1x1a':'t1x1a', + 'template1x2':'t1x2', + 'template2x1':'t2x1', + 'template2x2':'t2x2', + 'textsize':'textsize', + 'toppos':'tpos', + 'vspace':'nop', + 'wait':'wait', + 'width':'hres', + 'xcor':'xcor', + 'ycor':'ycor', + 'yellow':'yellow'} + +# +# block default values +# + +DEFAULTS = { + 'addturtle':[1], + 'arc':[90,100], + 'audio':[None], + 'back':[100], + 'box':[_('my box')], + 'description':[None], + 'fillscreen':[60,80], + 'forward':[100], + 'hat':[_('action')], + 'if':[None, None, 'vspace'], + 'ifelse':[None,'vspace', None, 'vspace'], + 'journal':[None], + 'left':[90], + 'media':[None], + 'myfunc':[_('x'),100], + 'nop':[100], + 'number':[100], + 'random':[0,100], + 'repeat':[4, None, 'vspace'], + 'right':[90], + 'setcolor':[0], + 'setheading':[0], + 'setpensize':[5], + 'setscale':[33], + 'setshade':[50], + 'settextsize':[32], + 'setxy':[0,0], + 'show':[_('text')], + 'stack':[_('action')], + 'storeinbox1':[100], + 'storeinbox2':[100], + 'storein':[_('my box'),100], + 'string':[_('text')], + 'template1x1':[_('Title'), 'None'], + 'template1x1a':[_('Title'), 'None'], + 'template1x2':[_('Title'), 'None', 'None'], + 'template2x1':[_('Title'), 'None', 'None'], + 'template2x2':[_('Title'), 'None', 'None', 'None', 'None'], + 'templatelist':[_('Title'), '∙ '], + 'wait':[1]} + +# +# Blocks that can interchange strings and numbers for their arguments +# +STRING_OR_NUMBER_ARGS = ['plus2', 'equal2', 'less2', 'greater2', + 'template1x1', 'template1x2', 'template2x1', + 'template2x2', 'template1x1a', 'templatelist', 'nop', + 'print', 'stack', 'hat'] + +CONTENT_ARGS = ['show', 'push', 'storein', 'storeinbox1', 'storeinbox2'] + +# +# Status blocks +# + +MEDIA_SHAPES = ['audiooff', 'audioon', 'audiosmall', + 'journaloff', 'journalon', 'journalsmall', + 'descriptionoff', 'descriptionon', 'descriptionsmall', + 'pythonoff', 'pythonon', 'pythonsmall', + 'list', '1x1', '1x1a', '2x1', '1x2', '2x2'] + +OVERLAY_SHAPES = ['Cartesian', 'polar'] + +STATUS_SHAPES = ['status', 'info', 'nostack', 'noinput', 'emptyheap', + 'emptybox', 'nomedia', 'nocode', 'overflowerror', + 'syntaxerror'] + +# +# Legacy names +# +OLD_NAMES = {'product':'product2', 'storeinbox':'storein', + 'division':'division2', 'plus':'plus2', 'and':'and2', 'or':'or2', + 'less':'less2', 'greater':'greater2', 'equal':'equal2', + 'remainder':'remainder2', 'identity':'identity2', + 'division':'division2', 'if else':'if', 'audiooff':'audio', + 'descriptionoff':'description','template3':'templatelist', + 'template1':'template1x1', 'template2':'template2x1', + 'template6':'template1x2', 'template7':'template2x2', + 'template4':'template1x1a', 'hres':'width', 'vres':'height' } + +# +# Define the relative size and postion of media objects +# (w, h, x, y, dx, dy) +# +TEMPLATES = {'t1x1': (0.5, 0.5, 0.0625, 0.125, 1.05, 0), + 't2z1': (0.5, 0.5, 0.0625, 0.125, 1.05, 1.05), + 't1x2': (0.45, 0.45, 0.0625, 0.125, 1.05, 1.05), + 't2x2': (0.45, 0.45, 0.0625, 0.125, 1.05, 1.05), + 't1x1a': (0.9, 0.9, 0.0625, 0.125, 0, 0), + 'bullet': (1, 1, 0.0625, 0.125, 0, 0.1), + 'insertimage': (0.333, 0.333)} + +# +# Names for blocks without names for popup help +# +SPECIAL_NAMES = { + 'audio':_('audio'), + 'division2':_('divide'), + 'equal2':_('equal'), + 'greater2':_('greater than'), + 'hspace':_('horizontal space'), + 'identity2':_('identity'), + 'if':_('if then'), + 'ifelse':_('if then else'), + 'journal':_('journal'), + 'less2':_('less than'), + 'minus2':_('minus'), + 'myfunc':_('Python code'), + 'nop':_('Python code'), + 'number':_('number'), + 'plus2':_('plus'), + 'product2':_('multiply'), + 'sqrt':_('square root'), + 'template1x1':_('presentation 1x1'), + 'template1x1a':_('presentation 1x1'), + 'template1x2':_('presentation 1x2'), + 'template2x1':_('presentation 2x1'), + 'template2x2':_('presentation 2x2'), + 'templatelist':_('presentation bulleted list'), + 'textsize':_('text size'), + 'vspace':_('vertical space')} + +# +# Help messages +# +HELP_STRINGS = { + 'addturtle':_("choose which turtle to command"), + 'and2':_("logical AND operator"), + 'arc':_("move turtle along an arc"), + 'audio':_("Sugar Journal audio object"), + 'back':_("move turtle backward"), + 'blocks':_("palette of variable blocks"), + 'bottompos':_("ycor of bottom of screen"), + 'box1':_("variable 1 (numeric value)"), + 'box2':_("variable 2 (numeric value)"), + 'box':_("named variable (numeric value)"), + 'clean':_("clear the screen and reset the turtle"), + 'clearheap':_("empty FILO"), + 'color':_("holds current pen color (can be used in place of a number block)"), + 'colors':_("a palette of pen colors"), + 'description':_("Sugar Journal description field"), + 'division2':_("divides top numeric input (numerator) by bottom numeric input (denominator)"), + 'equal2':_("logical equal-to operator"), + 'extras':_("palette of extra options"), + 'fillscreen':_("fills the background with (color, shade)"), + 'flow':_("palette of flow operators"), + 'forever':_("loop forever"), + 'forward':_("move turtle forward"), + 'greater2':_("logical greater-than operator"), + 'hat1':_("top of action 1 stack"), + 'hat2':_("top of action 2 stack"), + 'hat':_("top of nameable action stack"), + 'heading':_("holds current heading value of the turtle (can be used in place of a number block)"), + 'hideblocks':_("declutter canvas by hiding blocks"), + 'width':_("the canvas width"), + 'hspace':_("jog stack right"), + 'identity2':_("identity operator used for extending blocks"), + 'ifelse':_("if-then-else operator that uses boolean operators from Numbers palette"), + 'if':_("if-then operator that uses boolean operators from Numbers palette"), + 'journal':_("Sugar Journal media object"), + 'kbinput':_("query for keyboard input (results stored in keyboard block)"), + 'keyboard':_("holds results of query-keyboard block"), + 'leftpos':_("xcor of left of screen"), + 'left':_("turn turtle counterclockwise (angle in degrees)"), + 'less2':_("logical less-than operator"), + 'minus2':_("subtracts bottom numeric input from top numeric input"), + 'myfunc':_("a programmable block: add your own math equation in the block, e.g., sin(x)"), + 'nop':_("runs code found in the tamyblock.py module found in the Journal"), + 'not':_("logical NOT operator"), + 'numbers':_("palette of numeric operators"), + 'number':_("used as numeric input in mathematic operators"), + 'or':_("logical OR operator"), + 'orientation':_("changes the orientation of the palette of blocks"), + 'pendown':_("turtle will draw when moved"), + 'pen':_("palette of pen commands"), + 'pensize':_("holds current pen size (can be used in place of a number block)"), + 'penup':_("turtle will not draw when moved"), + 'plus2':_("adds two numeric inputs"), + 'pop':_("pop value off FILO"), + 'portfolio':_("palette of presentation templates"), + 'print':_("prints value in status block at bottom of the screen"), + 'printheap':_("show FILO in status block"), + 'product2':_("multiplies two numeric inputs"), + 'push':_("push value onto FILO (first-in last-out) heap"), + 'random':_("returns random number between minimum (left) and maximum (right) values"), + 'remainder2':_("modular (remainder) operator"), + 'repeat':_("loop specified number of times"), + 'restore':_("restore blocks from trash"), + 'rightpos':_("xcor of right of screen"), + 'right':_("turn turtle clockwise (angle in degrees)"), + 'scale':_("holds current scale value (can be used in place of a number block)"), + 'setcolor':_("set color of the line drawn by the turtle"), + 'seth':_("set the heading of the turtle (0 is towards the top of the screen.)"), + 'setpensize':_("set size of the line drawn by the turtle"), + 'setscale':_("set the scale of media"), + 'setshade':_("set shade of the line drawn by the turtle"), + 'settextcolor':_("set color of text drawn by the turtle"), + 'settextsize':_("set size of text drawn by turtle"), + 'setxy':_("move turtle to position xcor, ycor; (0, 0) is in the center of the screen."), + 'shade':_("holds current pen shade (can be used in place of a number block)"), + 'show':_("draw text or show media from the Journal"), + 'showblocks':_("restores hidden blocks"), + 'sqrt':_("calculate square root"), + 'stack1':_("invoke action 1 stack"), + 'stack2':_("invoke action 2 stack"), + 'stack':_("invoke named action stack"), + 'start':_("connects action to toolbar run buttons"), + 'stopstack':_("do not continue current action"), + 'storeinbox1':_("store numeric value in variable 1"), + 'storeinbox2':_("store numeric value in variable 2"), + 'storein':_("store numeric value in named variable"), + 'string':_("string value"), + '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"), + 'textcolor':_("holds current text color (can be used in place of a number block)"), + 'textsize':_("holds current text size (can be used in place of a number block)"), + 'toppos':_("ycor of top of screen"), + 'trash':_("a place to throw away blocks"), + 'turtle':_("palette of turtle commands"), + 'height':_("the canvas height"), + 'vspace':_("jog stack down"), + 'wait':_("wait specified number of seconds"), + 'xcor':_("holds current x-coordinate value of the turtle (can be used in place of a number block)"), + 'ycor':_("holds current y-coordinate value of the turtle (can be used in place of a number block)")} + + +# +# 'dead key' Unicode dictionaries +# + +DEAD_KEYS = ['grave','acute','circumflex','tilde','diaeresis','abovering'] +DEAD_DICTS = [{'A':192,'E':200,'I':204,'O':210,'U':217,'a':224,'e':232,'i':236, + 'o':242,'u':249}, + {'A':193,'E':201,'I':205,'O':211,'U':218,'a':225,'e':233,'i':237, + 'o':243,'u':250}, + {'A':194,'E':202,'I':206,'O':212,'U':219,'a':226,'e':234, + 'i':238,'o':244,'u':251}, + {'A':195,'O':211,'N':209,'U':360,'a':227,'o':245,'n':241,'u':361}, + {'A':196,'E':203,'I':207,'O':211,'U':218,'a':228,'e':235, + 'i':239,'o':245,'u':252}, + {'A':197,'a':229}] +NOISE_KEYS = ['Shift_L', 'Shift_R', 'Control_L', 'Caps_Lock', 'Pause', + 'Alt_L', 'Alt_R', 'KP_Enter', 'ISO_Level3_Shift', 'KP_Divide', + 'Escape', 'Return', 'KP_Page_Up', 'Up', 'Down', 'Menu', + 'Left', 'Right', 'KP_Home', 'KP_End', 'KP_Up', 'Super_L', + 'KP_Down', 'KP_Left', 'KP_Right', 'KP_Page_Down', 'Scroll_Lock', + 'Page_Down', 'Page_Up'] +WHITE_SPACE = ['space','Tab'] + +CURSOR = '█' @@ -35,7 +35,7 @@ try: except: pass -from constants import * +from taconstants import * from tagplay import play_audio, play_movie_from_file, stop_media from tajail import myfunc, myfunc_import from tautils import get_pixbuf_from_journal, movie_media_type,\ diff --git a/taturtle.py b/taturtle.py index 9170413..0933c0c 100644 --- a/taturtle.py +++ b/taturtle.py @@ -19,7 +19,7 @@ #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN #THE SOFTWARE. -from constants import * +from taconstants import * from sprite_factory import SVG, svg_str_to_pixbuf import sprites from gettext import gettext as _ diff --git a/tawindow.py b/tawindow.py index e598824..3a463aa 100644 --- a/tawindow.py +++ b/tawindow.py @@ -36,24 +36,25 @@ import gobject import os import os.path import time - from math import atan2, pi DEGTOR = 2*pi/360 -from constants import * +from gettext import gettext as _ + try: from sugar.graphics.objectchooser import ObjectChooser from sugar.datastore import datastore except: pass -from gettext import gettext as _ -from tautils import * -from sprite_factory import SVG, svg_str_to_pixbuf +from taconstants import * from talogo import LogoCode, stop_logo from tacanvas import TurtleGraphics -from sprites import Sprites, Sprite -from block import Blocks, Block +from tablock import Blocks, Block from taturtle import Turtles, Turtle +from tautils import magnitude, get_load_name, get_save_name, data_from_file,\ + data_to_file, round_int, get_id, get_pixbuf_from_journal +from sprite_factory import SVG, svg_str_to_pixbuf +from sprites import Sprites, Sprite """ TurtleArt Window class abstraction diff --git a/turtleart.py b/turtleart.py index 967967e..e992028 100755 --- a/turtleart.py +++ b/turtleart.py @@ -29,7 +29,7 @@ import os.path import locale from gettext import gettext as _ -from tawindow import * +from tawindow import TurtleArtWindow """ Make a path if it doesn't previously exist |