diff options
Diffstat (limited to 'TurtleArt')
-rw-r--r-- | TurtleArt/tablock.py | 37 | ||||
-rw-r--r-- | TurtleArt/taconstants.py | 2 | ||||
-rw-r--r-- | TurtleArt/talogo.py | 70 | ||||
-rw-r--r-- | TurtleArt/tapalette.py | 2 | ||||
-rwxr-xr-x | TurtleArt/tasprite_factory.py | 86 | ||||
-rw-r--r-- | TurtleArt/tawindow.py | 22 |
6 files changed, 171 insertions, 48 deletions
diff --git a/TurtleArt/tablock.py b/TurtleArt/tablock.py index cd5515e..3b9650f 100644 --- a/TurtleArt/tablock.py +++ b/TurtleArt/tablock.py @@ -209,7 +209,7 @@ class Block: self._visible = True self.unknown = False # Block is of unknown style - self.block_methods = { + self._block_methods = { 'basic-style': self._make_basic_style, 'blank-style': self._make_blank_style, 'basic-style-head': self._make_basic_style_head, @@ -241,6 +241,7 @@ class Block: 'clamp-style-collapsed': self._make_clamp_style_collapsed, 'clamp-style-1arg': self._make_clamp_style_1arg, 'clamp-style-boolean': self._make_clamp_style_boolean, + 'clamp-style-until': self._make_clamp_style_until, 'clamp-style-else': self._make_clamp_style_else, 'flow-style-tail': self._make_flow_style_tail, 'portfolio-style-2x2': self._make_portfolio_style_2x2, @@ -679,7 +680,8 @@ class Block: y = self.docks[1][3] - int(int(self.font_size[0] * 1.3)) self.spr.set_label_attributes(int(self.font_size[0] + 0.5), True, 'right', y_pos=y, i=0) - elif self.name in block_styles['clamp-style-boolean']: + elif self.name in block_styles['clamp-style-boolean'] or \ + self.name in block_styles['clamp-style-until']: y = self.docks[1][3] - int(int(self.font_size[0] * 1.3)) self.spr.set_label_attributes(int(self.font_size[0] + 0.5), True, 'right', y_pos=y, i=0) @@ -709,19 +711,18 @@ class Block: self._right = 0 self._bottom = 0 self.svg.set_stroke_width(STANDARD_STROKE_WIDTH) - self.svg.clear_docks() if isinstance(self.name, unicode): self.name = self.name.encode('utf-8') for k in block_styles.keys(): if self.name in block_styles[k]: - if isinstance(self.block_methods[k], list): - self.block_methods[k][0](svg, self.block_methods[k][1], - self.block_methods[k][2]) + if isinstance(self._block_methods[k], list): + self._block_methods[k][0](svg, self._block_methods[k][1], + self._block_methods[k][2]) else: - self.block_methods[k](svg) + self._block_methods[k](svg) return error_output('ERROR: block type not found %s' % (self.name)) - self.block_methods['blank-style'](svg) + self._block_methods['blank-style'](svg) self.unknown = True def _set_colors(self, svg): @@ -1086,6 +1087,24 @@ class Block: ['flow', False, self.svg.docks[4][0], self.svg.docks[4][1], ']']] + def _make_clamp_style_until(self, svg, extend_x=0, extend_y=4): + self.svg.expand(self.dx + self.ex + extend_x, self.ey + extend_y) + self.svg.set_slot(True) + self.svg.set_tab(True) + self.svg.set_boolean(True) + self.svg.second_clamp(False) + self._make_block_graphics(svg, self.svg.clamp_until) + # Dock positions are flipped + self.docks = [['flow', True, self.svg.docks[0][0], + self.svg.docks[0][1]], + ['bool', False, self.svg.docks[3][0], + self.svg.docks[3][1]], + ['flow', False, self.svg.docks[1][0], + self.svg.docks[1][1], '['], + # Skip bottom of clamp + ['flow', False, self.svg.docks[4][0], + self.svg.docks[4][1], ']']] + def _make_clamp_style_else(self, svg, extend_x=0, extend_y=4): self.svg.expand(self.dx + self.ex + extend_x, self.ey + extend_y, self.dx + self.ex + extend_x, self.ey2 + extend_y) @@ -1194,6 +1213,7 @@ class Block: def _make_block_graphics(self, svg, function, arg=None): self._set_colors(svg) self.svg.set_gradient(True, GRADIENT_COLOR) + self.svg.clear_docks() if arg is None: pixbuf = svg_str_to_pixbuf(function()) else: @@ -1203,6 +1223,7 @@ class Block: self.shapes[0] = _pixbuf_to_cairo_surface(pixbuf, self.width, self.height) self.svg.set_gradient(False) + self.svg.clear_docks() if arg is None: pixbuf = svg_str_to_pixbuf(function()) else: diff --git a/TurtleArt/taconstants.py b/TurtleArt/taconstants.py index 78cb9e1..75288c1 100644 --- a/TurtleArt/taconstants.py +++ b/TurtleArt/taconstants.py @@ -341,6 +341,8 @@ VOICES = {'af': 'afrikaans', 'cy': 'welsh-test', 'el': 'greek', MACROS = { 'ifthenelse': # Because it is too big to fit on the palette [[0, 'ifelse', 0, 0, [None, None, None, None, None]]], + 'untilmacro': # Because it is too big to fit on the palette + [[0, 'until', 0, 0, [None, None, None, None]]], 'kbinput': [[0, 'until', 0, 0, [None, 1, 4, None]], [1, 'greater2', 0, 0, [0, 2, 3, None]], diff --git a/TurtleArt/talogo.py b/TurtleArt/talogo.py index 67aa32c..5792043 100644 --- a/TurtleArt/talogo.py +++ b/TurtleArt/talogo.py @@ -835,24 +835,35 @@ class LogoCode: name = float(name) return 'stack3' + str(name) - def load_heap(self, path): + def load_heap(self, obj): """ Load FILO from file """ if self.tw.running_sugar: - # Choose a datastore object and push data to heap (Sugar only) - chooser_dialog(self.tw.parent, path, self.push_file_data_to_heap) + # Is the object a dsobject? + if isinstance(obj, Media) and obj.value: + from sugar.datastore import datastore + try: + dsobject = datastore.get(obj.value) + except: + debug_output("Couldn't find dsobject %s" % + (obj.value), self.tw.running_sugar) + if dsobject is not None: + self.push_file_data_to_heap(dsobject) + # Or is it a path? + elif os.path.exists(obj): + self.push_file_data_to_heap(None, path=obj) + else: + # Finally try choosing a datastore object + chooser_dialog(self.tw.parent, obj, + self.push_file_data_to_heap) else: - if not os.path.exists(path): - path, self.tw.load_save_folder = get_load_name( + # If you cannot find the file, open a chooser. + if not os.path.exists(obj): + obj, self.tw.load_save_folder = get_load_name( '.*', self.tw.load_save_folder) - if path is None: - return + if obj is not None: + self.push_file_data_to_heap(None, path=obj) - data = data_from_file(path) - if data is not None: - for val in data: - self.heap.append(val) - - def save_heap(self, path): + def save_heap(self, obj): """ save FILO to file """ if self.tw.running_sugar: from sugar import profile @@ -861,22 +872,23 @@ class LogoCode: # Save JSON-encoded heap to temporary file heap_file = os.path.join(get_path(activity, 'instance'), - str(path) + '.txt') + 'heap.txt') data_to_file(self.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' + # Write to an existing or new dsobject + if isinstance(obj, Media) and obj.value: + dsobject = datastore.get(obj.value) + else: + dsobject = datastore.create() + dsobject.metadata['title'] = str(obj) + 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 + heap_file = obj data_to_file(self.heap, heap_file) def get_heap(self): @@ -1011,7 +1023,7 @@ class LogoCode: self.filepath = None self.dsobject = None - if os_path_exists(obj.value): # file path + if obj.value is not None and os_path_exists(obj.value): self.filepath = obj.value elif self.tw.running_sugar: # datastore object from sugar.datastore import datastore @@ -1172,9 +1184,15 @@ class LogoCode: int(self.tw.canvas.textsize * self.scale / 100.), self.tw.canvas.width - x) - def push_file_data_to_heap(self, dsobject): + def push_file_data_to_heap(self, dsobject, path=None): """ push contents of a data store object (assuming json encoding) """ - data = data_from_file(dsobject.file_path) + if dsobject: + data = data_from_file(dsobject.file_path) + elif path is not None: + data = data_from_file(path) + else: + data = None + debug_output("No file to open", self.tw.running_sugar) if data is not None: for val in data: self.heap.append(val) diff --git a/TurtleArt/tapalette.py b/TurtleArt/tapalette.py index fd8fac7..2cf568a 100644 --- a/TurtleArt/tapalette.py +++ b/TurtleArt/tapalette.py @@ -71,6 +71,7 @@ block_styles = {'basic-style': [], 'clamp-style-collapsed': [], 'clamp-style-1arg': [], 'clamp-style-boolean': [], + 'clamp-style-until': [], 'clamp-style-else': [], 'portfolio-style-2x2': [], 'portfolio-style-1x1': [], @@ -289,6 +290,7 @@ class _ProtoBlock(): 'clamp-style-collapsible', 'clamp-style-1arg', 'clamp-style-boolean', + 'clamp-style-until', 'clamp-style-else']: EXPANDABLE_FLOW.append(self._name) diff --git a/TurtleArt/tasprite_factory.py b/TurtleArt/tasprite_factory.py index 2bd8993..7f9494c 100755 --- a/TurtleArt/tasprite_factory.py +++ b/TurtleArt/tasprite_factory.py @@ -609,6 +609,61 @@ stroke-width="3.5" fill="%s" stroke="none" />\n' % (self._stroke) svg += self.footer() return self.header() + svg + def clamp_until(self): + ''' Until block is like clamp but docks are flipped ''' + self.reset_min_max() + x = self._stroke_width / 2.0 + y = self._stroke_width / 2.0 + self._radius + self.margins[0] = int((x + self._stroke_width + 0.5) * self._scale) + self.margins[1] = int((self._stroke_width + 0.5) * self._scale) + self.margins[2] = 0 + self.margins[3] = 0 + svg = self.new_path(x, y) + svg += self._corner(1, -1) + svg += self._do_slot() + svg += self._rline_to(self._radius + self._stroke_width, 0) + svg += self._rline_to(self._expand_x, 0) + xx = self._x + svg += self._corner(1, 1, skip=True) + svg += self._corner(-1, 1, skip=True) + svg += self.line_to(xx, self._y) + svg += self._rline_to(-self._expand_x, 0) + svg += self._do_tab() + svg += self._inverse_corner(-1, 1, 90, 0, 0) + svg += self._rline_to(0, self._expand_y) + svg += self._inverse_corner(1, 1, 90, 0, 0) + svg += self._do_slot() + svg += self._rline_to(self._radius, 0) + if self._second_clamp: + svg += self._corner(-1, 1) + svg += self.line_to(xx, self._y) + svg += self._rline_to(-self._expand_x, 0) + svg += self._do_tab() + svg += self._inverse_corner(-1, 1, 90, 0, 0) + svg += self._rline_to(0, self._expand_y2) + svg += self._inverse_corner(1, 1, 90, 0, 0) + svg += self._do_slot() + svg += self._rline_to(self._radius, 0) + if self._innie[0] is True: + svg += self._do_innie() + else: + self.margins[2] = \ + int((self._x - self._stroke_width + 0.5) * self._scale) + svg += self._rline_to(0, self._radius * 3) + if self._bool is True: + svg += self._do_boolean() + svg += self._corner(-1, 1) + svg += self._rline_to(-self._radius - self._stroke_width, 0) + svg += self._do_tab() + svg += self._corner(-1, -1) + svg += self._close_path() + self.calc_w_h() + svg += self.style() + if self._collapsible: + svg += self._hide_dot() + svg += self.footer() + return self.header() + svg + def status_block(self, graphic=None): ''' Generate a status block ''' self.reset_min_max() @@ -950,7 +1005,8 @@ stroke-width="3.5" fill="%s" stroke="none" />\n' % (self._stroke) 0) return svg_str - def _corner(self, sign_x, sign_y, a=90, l=0, s=1, start=True, end=True): + def _corner(self, sign_x, sign_y, a=90, l=0, s=1, start=True, end=True, + skip=False): svg_str = "" if sign_x == 1 and sign_y == -1: # Upper-left corner self._hide_x = self._x + self._radius + self._stroke_width @@ -970,7 +1026,7 @@ stroke-width="3.5" fill="%s" stroke="none" />\n' % (self._stroke) if start: if sign_x * sign_y == 1: svg_str += self._rline_to(sign_x * r2, 0) - else: + elif not skip: svg_str += self._rline_to(0, sign_y * r2) x = self._x + sign_x * r2 y = self._y + sign_y * r2 @@ -978,7 +1034,7 @@ stroke-width="3.5" fill="%s" stroke="none" />\n' % (self._stroke) if end: if sign_x * sign_y == 1: svg_str += self._rline_to(0, sign_y * r2) - else: + elif not skip: svg_str += self._rline_to(sign_x * r2, 0) return svg_str @@ -1237,6 +1293,7 @@ def close_file(f): def generator(datapath): + ''' svg = SVG() f = open_file(datapath, "turtle.svg") svg.set_scale(2) @@ -1471,29 +1528,42 @@ def generator(datapath): close_file(f) svg = SVG() - f = open_file(datapath, "clampb.svg") + f = open_file(datapath, "clampe.svg") svg.set_scale(2) svg.expand(30, 0, 0, 0) svg.set_slot(True) svg.set_tab(True) svg.set_boolean(True) - svg.second_clamp(False) + svg.second_clamp(True) svg_str = svg.clamp() f.write(svg_str) close_file(f) + ''' svg = SVG() - f = open_file(datapath, "clampe.svg") + f = open_file(datapath, "clampb.svg") svg.set_scale(2) - svg.expand(30, 0, 0, 0) + svg.expand(0, 30, 0, 0) svg.set_slot(True) svg.set_tab(True) svg.set_boolean(True) - svg.second_clamp(True) + svg.second_clamp(False) svg_str = svg.clamp() f.write(svg_str) close_file(f) + svg = SVG() + f = open_file(datapath, "clampu.svg") + svg.set_scale(2) + svg.expand(0, 30, 0, 0) + svg.set_slot(True) + svg.set_tab(True) + svg.set_boolean(True) + svg.second_clamp(False) + svg_str = svg.clamp_until() + f.write(svg_str) + close_file(f) + def main(): return 0 diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py index 2aa8f89..2f0a036 100644 --- a/TurtleArt/tawindow.py +++ b/TurtleArt/tawindow.py @@ -2553,8 +2553,9 @@ before making changes to your program')) if blk is None: continue if blk.name in EXPANDABLE_FLOW: - if blk.name in block_styles['clamp-style-1arg'] or\ - blk.name in block_styles['clamp-style-boolean']: + if blk.name in block_styles['clamp-style-1arg'] or \ + blk.name in block_styles['clamp-style-boolean'] or \ + blk.name in block_styles['clamp-style-until']: if blk.connections[2] is not None: self._resize_clamp(blk, blk.connections[2]) elif blk.name in block_styles['clamp-style']: @@ -3391,7 +3392,9 @@ before making changes to your program')) if best_destination.name in \ block_styles['clamp-style-1arg'] or \ best_destination.name in \ - block_styles['clamp-style-boolean']: + block_styles['clamp-style-boolean'] or \ + best_destination.name in \ + block_styles['clamp-style-until']: if best_destination_dockn == 2: self._resize_clamp(best_destination, self.drag_group[0]) @@ -3492,8 +3495,9 @@ before making changes to your program')) self._expand_expandable(blk2, blk, dy) self._cascade_expandable(blk2) elif c is not None and blk2.name in EXPANDABLE_FLOW: - if blk2.name in block_styles['clamp-style-1arg'] or\ - blk2.name in block_styles['clamp-style-boolean']: + if blk2.name in block_styles['clamp-style-1arg'] or \ + blk2.name in block_styles['clamp-style-boolean'] or \ + blk2.name in block_styles['clamp-style-until']: if c == 2: self._resize_clamp(blk2, None, c) elif blk2.name in block_styles['clamp-style'] or \ @@ -3542,12 +3546,18 @@ before making changes to your program')) drag_group = find_group(blk.connections[-1]) for gblk in drag_group: gblk.spr.move_relative((0, y2-y1)) - # We may have to move the else clamp group down too. + # We may have to move the else clamp group up or down too. if blk.name in block_styles['clamp-style-else'] and dockn == 2: if blk.connections[3] is not None: drag_group = find_group(blk.connections[3]) for gblk in drag_group: gblk.spr.move_relative((0, y2 - y1)) + # We may have to move the bool group up or down too. + if blk.name in block_styles['clamp-style-until']: + if blk.connections[1] is not None: + drag_group = find_group(blk.connections[1]) + for gblk in drag_group: + gblk.spr.move_relative((0, y2 - y1)) def _expandable_flow_above(self, blk): ''' Is there an expandable flow block above this one? ''' |