From cd0466e89490b890d69dc6d25cfe78cf2dab3750 Mon Sep 17 00:00:00 2001 From: Walter Bender Date: Fri, 15 Jun 2012 18:47:57 +0000 Subject: add proto blocks for named stacks --- diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py index ebe952c..d117eef 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 from tacanvas import TurtleGraphics from tablock import Blocks, Block from taturtle import Turtles, Turtle @@ -173,6 +174,7 @@ class TurtleArtWindow(): self.coord_scale = 1 self.buddies = [] self.saved_string = '' + self._saved_action_name = '' self.dx = 0 self.dy = 0 self.media_shapes = {} @@ -1189,6 +1191,11 @@ class TurtleArtWindow(): n -= 1 self.selected_blk.spr.set_label(str(n) + CURSOR) return True + elif self._action_name(self.selected_blk, hat_only=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]) + # Un-highlight any blocks in the stack grp = find_group(self.selected_blk) for blk in grp: @@ -1225,6 +1232,8 @@ class TurtleArtWindow(): elif blk.type == 'trash': self._restore_from_trash(find_top_block(blk)) elif blk.type == 'proto': + defaults = None + name = blk.name if blk.name == 'restoreall': self._restore_all_from_trash() elif blk.name == 'restore': @@ -1244,6 +1253,11 @@ class TurtleArtWindow(): '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' # You cannot mix and match sensor blocks elif blk.name in ['sound', 'volume', 'pitch']: if len(self.block_list.get_similar_blocks( @@ -1269,7 +1283,10 @@ class TurtleArtWindow(): self.showlabel('incompatible') return True blk.highlight() - self._new_block(blk.name, x, y) + if defaults == None: + self._new_block(name, x, y) + else: + self._new_block(name, x, y, defaults=defaults) blk.unhighlight() return True @@ -1327,6 +1344,44 @@ 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 self._saved_action_name: + self._saved_action_name = \ + self._saved_action_name.replace(CURSOR, '') + if CURSOR in name: + name = name.replace(CURSOR, '') + for blk in self.just_blocks(): + if self._action_name(blk): + 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) + # Also change the name of the proto block + for blk in self.just_protos(): + if blk.name == 'stack_%s' % (self._saved_action_name): + blk.name = 'stack_%s' % (name) + blk.spr.labels[0] = name + blk.spr.set_layer(PROTO_LAYER) + return + + def _action_name(self, blk, hat_only=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 self.selected_blk.connections[0] is None: + return False + if self.selected_blk.connections[0].name in ['hat', 'stack']: + if hat_only and self.selected_blk.connections[0].name =='stack': + return False + return True + return False + def _select_category(self, spr): """ Select a category from the toolbar """ i = self.selectors.index(spr) @@ -1401,6 +1456,18 @@ class TurtleArtWindow(): for gblk in group: gblk.spr.hide() + # if there was a named hat, 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') + palette_blocks[i].remove('stack_%s' % ( + gblk.connections[1].values[0])) + 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: @@ -1478,7 +1545,7 @@ class TurtleArtWindow(): def _unselect_block(self): """ Unselect block """ - # After unselecting a 'number' block, we need to check its value + # After unselecting a 'number' or 'string' block, check its value if self.selected_blk.name == 'number': self._number_check() for spr in self.triangle_sprs: @@ -2020,8 +2087,16 @@ class TurtleArtWindow(): return self.selected_blk = blk - if blk.name == 'number' or blk.name == 'string': + if blk.name == 'number' or blk.name == 'string': self.saved_string = blk.spr.labels[0] + if self._action_name(blk): + if CURSOR in self.saved_string: + self._saved_action_name = \ + self.saved_string.replace(CURSOR, '') + else: + self._saved_action_name = self.saved_string + else: + self._saved_action_name = None blk.spr.labels[0] += CURSOR if blk.name == 'number': bx, by = blk.spr.get_xy() @@ -3343,6 +3418,14 @@ class TurtleArtWindow(): just_blocks_list.append(_blk) return just_blocks_list + def just_protos(self): + """ Filter out 'blocks', '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 @@ -3423,6 +3506,49 @@ 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 _prim_stack(self, x): + """ Process a named stack """ + from TurtleArt.tautils import convert + from talogo import logoerror + + 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 dock_dx_dy(block1, dock1n, block2, dock2n): """ Find the distance between the dock points of two blocks. """ -- cgit v0.9.1