From 793b4cfa0bba78d0c7bc60cc24311135b49e3ef9 Mon Sep 17 00:00:00 2001 From: Walter Bender Date: Mon, 18 Jun 2012 19:51:43 +0000 Subject: add back in call to reload challenge after erase --- diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py index 44e95a6..fe55ee7 100644 --- a/TurtleArt/tawindow.py +++ b/TurtleArt/tawindow.py @@ -54,8 +54,9 @@ from taconstants import HORIZONTAL_PALETTE, VERTICAL_PALETTE, BLOCK_SCALE, \ CONSTANTS, EXPAND_SKIN, PROTO_LAYER from tapalette import palette_names, palette_blocks, expandable_blocks, \ block_names, content_blocks, default_values, special_names, block_styles, \ - help_strings, hidden_proto_blocks, string_or_number_args -from talogo import LogoCode + help_strings, hidden_proto_blocks, string_or_number_args, \ + make_palette, palette_name_to_index +from talogo import LogoCode, primitive_dictionary, logoerror from tacanvas import TurtleGraphics from tablock import Blocks, Block from taturtle import Turtles, Turtle @@ -67,7 +68,7 @@ from tautils import magnitude, get_load_name, get_save_name, data_from_file, \ collapsed, collapsible, hide_button_hit, show_button_hit, chooser, \ arithmetic_check, xy, find_block_to_run, find_top_block, journal_check, \ find_group, find_blk_below, data_to_string, find_start_stack, \ - get_hardware, debug_output, error_output, data_to_string + get_hardware, debug_output, error_output, data_to_string, convert from tasprite_factory import SVG, svg_str_to_pixbuf, svg_from_file from sprites import Sprites, Sprite @@ -135,6 +136,7 @@ class TurtleArtWindow(): self.mouse_flag = 0 self.mouse_x = 0 self.mouse_y = 0 + self.running_blocks = False try: locale.setlocale(locale.LC_NUMERIC, '') @@ -172,6 +174,8 @@ class TurtleArtWindow(): self.coord_scale = 1 self.buddies = [] self.saved_string = '' + self._saved_action_name = '' + self._saved_box_name = '' self.dx = 0 self.dy = 0 self.media_shapes = {} @@ -500,6 +504,8 @@ class TurtleArtWindow(): """ Run turtle! """ if self.running_sugar: self.activity.recenter() + if self.status_spr is not None: + self.status_spr.hide() # Look for a 'start' block for blk in self.just_blocks(): @@ -1187,7 +1193,24 @@ class TurtleArtWindow(): n -= 1 self.selected_blk.spr.set_label(str(n) + CURSOR) return True + elif self._action_name(self.selected_blk, hat=True): + if self.selected_blk.values[0] == _('action'): + self._new_stack_block(self.selected_blk.spr.labels[0]) + self._update_action_names(self.selected_blk.spr.labels[0]) + elif self._box_name(self.selected_blk, storein=True): + if self.selected_blk.values[0] == _('my box'): + self._new_box_block(self.selected_blk.spr.labels[0]) + self._update_box_names(self.selected_blk.spr.labels[0]) + # Un-highlight any blocks in the stack + grp = find_group(self.selected_blk) + for blk in grp: + if blk.status != 'collapsed': + blk.unhighlight() self._unselect_block() + if self.running_sugar and self._sharing and \ + hasattr(self.activity, 'share_button'): + self.activity.share_button.set_tooltip( + _('Select blocks to share')) self.selected_turtle = None # Always hide the status layer on a click @@ -1199,7 +1222,8 @@ class TurtleArtWindow(): self.dragging_canvas[1] = x self.dragging_canvas[2] = y if spr is None: - self.dragging_canvas[0] = True + if not self.running_blocks and not self.hw in (XO1, XO15, XO175): + self.dragging_canvas[0] = True return True self.dragging_canvas[0] = False self.selected_spr = spr @@ -1226,12 +1250,24 @@ class TurtleArtWindow(): elif blk.name in MACROS: self._new_macro(blk.name, x + 20, y + 20) else: + defaults = None + name = blk.name # You can only have one instance of some blocks if blk.name in ['start', 'hat1', 'hat2']: if len(self.block_list.get_similar_blocks( 'block', blk.name)) > 0: self.showlabel('dupstack') return True + # If we autogenerated a stack prototype, we need + # to change its name from 'stack_foo' to 'stack' + elif blk.name[0:6] == 'stack_': + defaults = [blk.name[6:]] + name = 'stack' + # If we autogenerated a box prototype, we need + # to change its name from 'box_foo' to 'box' + elif blk.name[0:4] == 'box_': + defaults = [blk.name[4:]] + name = 'box' # You cannot mix and match sensor blocks elif blk.name in ['sound', 'volume', 'pitch']: if len(self.block_list.get_similar_blocks( @@ -1257,7 +1293,7 @@ class TurtleArtWindow(): self.showlabel('incompatible') return True blk.highlight() - self._new_block(blk.name, x, y) + self._new_block(name, x, y, defaults=defaults) blk.unhighlight() return True @@ -1315,6 +1351,92 @@ class TurtleArtWindow(): self._select_toolbar_button(spr) return True + def _update_action_names(self, name): + """ change the label on action blocks of the same name """ + if CURSOR in name: + name = name.replace(CURSOR, '') + for blk in self.just_blocks(): + if self._action_name(blk, hat=False): + if CURSOR in blk.spr.labels[0]: + blk.spr.labels[0] = \ + blk.spr.labels[0].replace(CURSOR, '') + if blk.spr.labels[0] == self._saved_action_name: + blk.spr.labels[0] = name + blk.values[0] = name + blk.spr.set_layer(BLOCK_LAYER) + self._change_proto_name(name, 'stack_%s' % (self._saved_action_name), + 'stack_%s' % (name), 'basic-style-1arg') + + def _update_box_names(self, name): + """ change the label on box blocks of the same name """ + if CURSOR in name: + name = name.replace(CURSOR, '') + for blk in self.just_blocks(): + if self._box_name(blk, storein=False): + if CURSOR in blk.spr.labels[0]: + blk.spr.labels[0] = \ + blk.spr.labels[0].replace(CURSOR, '') + if blk.spr.labels[0] == self._saved_box_name: + blk.spr.labels[0] = name + blk.values[0] = name + blk.spr.set_layer(BLOCK_LAYER) + self._change_proto_name(name, 'box_%s' % (self._saved_box_name), + 'box_%s' % (name), 'number-style-1strarg') + + def _change_proto_name(self, name, old, new, style, palette='blocks'): + """ change the name of a proto block """ + for blk in self.just_protos(): + if blk.name == old: + blk.name = new + blk.spr.labels[0] = name + blk.spr.set_layer(PROTO_LAYER) + i = palette_name_to_index(palette) + if old in palette_blocks[i]: + j = palette_blocks[i].index(old) + palette_blocks[i][j] = new + if old in block_styles[style]: + block_styles[style].remove(old) + block_styles[style].append(new) + else: + debug_output('%s not in %s' % (old, block_styles[style]), + self.running_sugar) + if old in block_names: + del block_names[old] + block_names[new] = name + else: + debug_output('%s not in %s' % (old, block_names), + self.running_sugar) + blk.resize() + return + + def _action_name(self, blk, hat=False): + """ is this a label for an action block? """ + if blk is None: + return False + if blk.name != 'string': # Ignoring int names + return False + if blk.connections[0] is None: + return False + if hat and blk.connections[0].name == 'hat': + return True + if not hat and blk.connections[0].name == 'stack': + return True + return False + + def _box_name(self, blk, storein=False): + """ is this a label for a storein block? """ + if blk is None: + return False + if blk.name != 'string': # Ignoring int names + return False + if blk.connections[0] is None: + return False + if storein and blk.connections[0].name == 'storein': + return True + if not storein and blk.connections[0].name == 'box': + return True + return False + def _select_category(self, spr): """ Select a category from the toolbar """ i = self.selectors.index(spr) @@ -1335,15 +1457,20 @@ class TurtleArtWindow(): if spr.name == 'run-fastoff': self.lc.trace = 0 self.hideblocks() + self.display_coordinates(clear=True) self.run_button(0) elif spr.name == 'run-slowoff': self.lc.trace = 1 + self.showblocks() self.run_button(3) elif spr.name == 'debugoff': self.lc.trace = 1 + self.showblocks() self.run_button(6) elif spr.name == 'stopiton': self.stop_button() + self.display_coordinates() + self.showblocks() self.toolbar_shapes['stopiton'].hide() elif spr.name == 'eraseron': self.eraser_button() @@ -1384,6 +1511,29 @@ class TurtleArtWindow(): for gblk in group: gblk.spr.hide() + # if there was a named hat or storein, remove it from the proto palette + for gblk in group: + if gblk.name == 'hat' and \ + gblk.connections is not None and \ + gblk.connections[1] is not None and \ + gblk.connections[1].name == 'string' and \ + gblk.connections[1].values[0] != _('action'): + i = palette_name_to_index('blocks') + name = 'stack_%s' % (gblk.connections[1].values[0]) + if name in palette_blocks[i]: + palette_blocks[i].remove(name) + self.show_toolbar_palette(i, regenerate=True) + if gblk.name == 'storein' and \ + gblk.connections is not None and \ + gblk.connections[1] is not None and \ + gblk.connections[1].name == 'string' and \ + gblk.connections[1].values[0] != _('box'): + i = palette_name_to_index('blocks') + name = 'box_%s' % (gblk.connections[1].values[0]) + if name in palette_blocks[i]: + palette_blocks[i].remove(name) + self.show_toolbar_palette(i, regenerate=True) + def _restore_all_from_trash(self): """ Restore all the blocks in the trash can. """ for blk in self.block_list.list: @@ -1449,8 +1599,18 @@ class TurtleArtWindow(): for blk in self.drag_group: if blk.status != 'collapsed': blk.spr.set_layer(TOP_LAYER) + blk.highlight() + if self.running_sugar and self._sharing and \ + hasattr(self.activity, 'share_button'): + self.activity.share_button.set_tooltip( + _('Share selected blocks')) if len(blk.spr.labels) > 0: self.saved_string = blk.spr.labels[0] + self._saved_action_name = self.saved_string + self._saved_box_name = self.saved_string + debug_output('_block_pressed: %s (%s, %s)' % ( + self.saved_string, self._saved_action_name, + self._saved_box_name), self.running_sugar) else: self.saved_string = '' @@ -1968,9 +2128,9 @@ class TurtleArtWindow(): if turtle is not None: turtle.label_block = Block(self.block_list, self.sprite_list, 'turtle-label', 0, 0, - 'label', [], 1.0 / self.scale, + 'label', [], 2.0 / self.scale, colors) - turtle.label_block.spr.set_label_attributes(6.0 / self.scale) + turtle.label_block.spr.set_label_attributes(12.0 / self.scale) if len(name) > 6: turtle.label_block.spr.set_label(name[0:4] + '…') else: @@ -2238,6 +2398,7 @@ class TurtleArtWindow(): if len(self.block_list.get_similar_blocks('block', 'savesvg')) > 0: if self.canvas.cr_svg is None: self.canvas.setup_svg_surface() + self.running_blocks = True self._start_plugins() # Let the plugins know we are running. top = find_top_block(blk) self.lc.run_blocks(top, self.just_blocks(), True) @@ -2475,8 +2636,8 @@ class TurtleArtWindow(): self._process_numeric_input(keyname) elif self.selected_blk.name == 'string': self.process_alphanumeric_input(keyname, keyunicode) - if self.selected_blk is not None: - self.selected_blk.resize() + # if self.selected_blk is not None: + self.selected_blk.resize() elif self.selected_blk.name != 'proto': self._process_keyboard_commands(keyname, block_flag=True) @@ -2539,15 +2700,12 @@ class TurtleArtWindow(): elif len(self.selected_blk.spr.labels[0]) == 1: oldleft = '' oldright = '' - else: - try: # Why are getting a ValueError on occasion? - oldleft, oldright = \ - self.selected_blk.spr.labels[0].split(CURSOR) - except ValueError: - debug_output("[%s]" % self.selected_blk.spr.labels[0], - self.running_sugar) - oldleft = self.selected_blk.spr.labels[0] - oldright = '' + elif CURSOR in self.selected_blk.spr.labels[0]: + oldleft, oldright = \ + self.selected_blk.spr.labels[0].split(CURSOR) + else: # Where did our cursor go? + oldleft = self.selected_blk.spr.labels[0] + oldright = '' else: oldleft = '' oldright = '' @@ -2746,6 +2904,7 @@ class TurtleArtWindow(): s = self.selected_blk.spr.labels[0].replace(CURSOR, '') self.selected_blk.spr.set_label(s) self.selected_blk.values[0] = s.replace(RETURN, "\12") + self.saved_string = self.selected_blk.values[0] def load_python_code_from_file(self, fname=None, add_new_block=True): """ Load Python code from a file """ @@ -3169,18 +3328,28 @@ class TurtleArtWindow(): self.canvas.shade, self.canvas.pensize)) return _data - def display_coordinates(self): + def display_coordinates(self, clear=False): """ Display the coordinates of the current turtle on the toolbar """ - x = round_int(float(self.canvas.xcor) / self.coord_scale) - y = round_int(float(self.canvas.ycor) / self.coord_scale) - h = round_int(self.canvas.heading) - if self.running_sugar: - self.activity.coordinates_label.set_text("%s: %d %s: %d %s: %d" %\ - (_("xcor"), x, _("ycor"), y, _("heading"), h)) - self.activity.coordinates_label.show() - elif self.interactive_mode: - self.parent.set_title("%s — %s: %d %s: %d %s: %d" % \ - (_("Turtle Art"), _("xcor"), x, _("ycor"), y, _("heading"), h)) + if clear: + if self.running_sugar: + self.activity.coordinates_label.set_text('') + self.activity.coordinates_label.show() + elif self.interactive_mode: + self.parent.set_title('') + else: + x = round_int(float(self.canvas.xcor) / self.coord_scale) + y = round_int(float(self.canvas.ycor) / self.coord_scale) + h = round_int(self.canvas.heading) + if self.running_sugar: + self.activity.coordinates_label.set_text( + "%s: %d %s: %d %s: %d" % (_("xcor"), x, _("ycor"), y, + _("heading"), h)) + self.activity.coordinates_label.show() + elif self.interactive_mode: + self.parent.set_title( + "%s — %s: %d %s: %d %s: %d" % ( + _("Turtle Art"), _("xcor"), x, _("ycor"), y, + _("heading"), h)) def showlabel(self, shp, label=''): """ Display a message on a status block """ @@ -3305,11 +3474,19 @@ class TurtleArtWindow(): def just_blocks(self): """ Filter out 'proto', 'trash', and 'deleted' blocks """ just_blocks_list = [] - for _blk in self.block_list.list: - if _blk.type == 'block': - just_blocks_list.append(_blk) + for blk in self.block_list.list: + if blk.type == 'block': + just_blocks_list.append(blk) return just_blocks_list + def just_protos(self): + """ Filter out 'block', 'trash', and 'deleted' blocks """ + just_protos_list = [] + for blk in self.block_list.list: + if blk.type == 'proto': + just_protos_list.append(blk) + return just_protos_list + def _width_and_height(self, blk): """ What are the width and height of a stack? """ minx = 10000 @@ -3390,6 +3567,81 @@ class TurtleArtWindow(): x, y = self._calc_image_offset('', blk.spr, w, h) blk.scale_image(x, y, w, h) + def _new_stack_block(self, name): + ''' Add a stack block to the 'blocks' palette ''' + if CURSOR in name: + name = name.replace(CURSOR, '') + if name == _('action'): + return + # Choose a palette for the new block. + palette = make_palette('blocks') + + # Create a new block prototype. + primitive_dictionary['stack'] = self._prim_stack + palette.add_block('stack_%s' % (name), + style='basic-style-1arg', + label=name, + string_or_number=True, + prim_name='stack', + logo_command='action', + default=name, + help_string=_('invokes named action stack')) + self.lc.def_prim('stack', 1, primitive_dictionary['stack'], True) + + # Regenerate the palette, which will now include the new block. + self.show_toolbar_palette(palette_name_to_index('blocks'), + regenerate=True) + + def _new_box_block(self, name): + ''' Add a box block to the 'blocks' palette ''' + if CURSOR in name: + name = name.replace(CURSOR, '') + if name == _('box'): + return + # Choose a palette for the new block. + palette = make_palette('blocks') + + # Create a new block prototype. + primitive_dictionary['box'] = self._prim_box + palette.add_block('box_%s' % (name), + style='number-style-1strarg', + label=name, + string_or_number=True, + prim_name='box', + default=name, + logo_command='box', + help_string=_('named variable (numeric value)')) + self.lc.def_prim('box', 1, + lambda self, x: primitive_dictionary['box'](x)) + + # Regenerate the palette, which will now include the new block. + self.show_toolbar_palette(palette_name_to_index('blocks'), + regenerate=True) + + def _prim_stack(self, x): + """ Process a named stack """ + if type(convert(x, float, False)) == float: + if int(float(x)) == x: + x = int(x) + if 'stack3' + str(x) not in self.lc.stacks or \ + self.lc.stacks['stack3' + str(x)] is None: + raise logoerror("#nostack") + self.lc.icall(self.lc.evline, + self.lc.stacks['stack3' + str(x)][:]) + yield True + self.lc.procstop = False + self.lc.ireturn() + yield True + + def _prim_box(self, x): + """ Retrieve value from named box """ + if type(convert(x, float, False)) == float: + if int(float(x)) == x: + x = int(x) + try: + return self.lc.boxes['box3' + str(x)] + except KeyError: + raise logoerror("#emptybox") def dock_dx_dy(block1, dock1n, block2, dock2n): """ Find the distance between the dock points of two blocks. """ -- cgit v0.9.1