diff options
-rw-r--r-- | TurtleArt/tawindow.py | 138 | ||||
-rw-r--r-- | samples/math-galton-path.ta | 118 |
2 files changed, 193 insertions, 63 deletions
diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py index ebe952c..3c93fe9 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 = {} @@ -532,7 +534,7 @@ class TurtleArtWindow(): def stop_button(self): """ Stop button """ self.lc.stop_logo() - self._stop_plugins() + # self._stop_plugins() ## _stop_plugins is called from stop_logo() def set_userdefined(self, blk=None): """ Change icon for user-defined blocks after loading Python code. """ @@ -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. """ diff --git a/samples/math-galton-path.ta b/samples/math-galton-path.ta index b3f1567..4ba6997 100644 --- a/samples/math-galton-path.ta +++ b/samples/math-galton-path.ta @@ -1,57 +1,61 @@ -[[0, ["start", 1.5], 64, 216, [null, 27]], -[1, ["setxy2", 0], 792, 245, [4, 2, 3, 11]], -[2, ["number", 0], 845, 245, [1, null]], -[3, "toppos", 845, 277, [1, null]], -[4, "penup", 792, 213, [22, 1]], -[5, "repeat", 792, 340, [11, 6, 8, 7]], -[6, ["number", 70], 836, 340, [5, null]], -[7, ["vspace", 80], 792, 399, [5, 41]], -[8, ["setxy2", 60], 846, 385, [5, 16, 14, null]], -[9, ["number", -0.5], 1022, 449, [23, null]], -[10, ["number", -10], 940, 539, [14, null]], -[11, "pendown", 792, 308, [1, 5]], -[12, "setpensize", 64, 280, [27, 13, 28]], -[13, ["number", 1], 159, 280, [12, null]], -[14, ["plus2", 0], 899, 507, [8, 15, 10]], -[15, "ycor", 940, 507, [14, null]], -[16, ["plus2", 0], 899, 385, [8, 17, 24]], -[17, "xcor", 940, 385, [16, null]], -[18, ["random", 0], 1022, 481, [23, 19, 20, null]], -[19, ["number", 0], 1098, 481, [18, null]], -[20, ["number", 1], 1098, 513, [18, null]], -[21, "stack1", 118, 509, [26, null]], -[22, "hat1", 792, 181, [null, 4]], -[23, ["plus2", 0], 981, 449, [24, 9, 18]], -[24, ["product2", 0], 940, 417, [16, 25, 23]], -[25, ["number", 20], 981, 417, [24, null]], -[26, "forever", 64, 495, [32, 21, null]], -[27, "clean", 64, 248, [0, 12]], -[28, "storeinbox1", 64, 312, [12, 29, 30]], -[29, ["number", -400], 174, 312, [28, null]], -[30, "repeat", 64, 344, [28, 31, 33, 32]], -[31, ["number", 80], 108, 344, [30, null]], -[32, ["vspace", 40], 64, 403, [30, 26]], -[33, ["storein", 0], 118, 389, [30, 35, 34, 36]], -[34, ["number", 0], 180, 421, [33, null]], -[35, "box1", 180, 389, [33, null]], -[36, "storeinbox1", 118, 452, [33, 39, null]], -[37, ["number", 10], 269, 484, [39, null]], -[38, "box1", 269, 452, [39, null]], -[39, ["plus2", 0], 228, 452, [36, 38, 37]], -[40, ["storein", 0], 485, 196, [42, 50, 45, 48]], -[41, "stack2", 792, 551, [7, null]], -[42, "hat2", 485, 164, [null, 40]], -[43, "box", 588, 228, [45, 51, null]], -[44, "ycor", 237, 0, [null, null]], -[45, ["plus2", 0], 547, 228, [40, 43, 46]], -[46, ["number", 1], 588, 260, [45, null]], -[47, "forward", 485, 323, [53, 49, 55]], -[48, ["vspace", 0], 485, 259, [40, 53]], -[49, "box", 549, 323, [47, 52, null]], -[50, "xcor", 547, 196, [40, null]], -[51, "xcor", 635, 228, [43, null]], -[52, "xcor", 596, 323, [49, null]], -[53, "setpensize", 485, 291, [48, 54, 47]], -[54, ["number", 18], 580, 291, [53, null]], -[55, "setpensize", 485, 355, [47, 56, null]], -[56, ["number", 1], 580, 355, [55, null]]]
\ No newline at end of file +[[0, ["start", 1.5], 20, 20, [null, 27]], +[1, ["setxy2", 0], 480, 84, [4, 2, 3, 11]], +[2, ["number", 0], 524, 84, [1, null]], +[3, "toppos", 524, 116, [1, null]], +[4, "penup", 480, 52, [22, 1]], +[5, "repeat", 480, 179, [11, 6, 8, 7]], +[6, ["number", 70], 519, 179, [5, null]], +[7, ["vspace", 80], 480, 238, [5, 35]], +[8, ["setxy2", 80], 529, 224, [5, 16, 14, null]], +[9, ["number", -0.5], 696, 288, [23, null]], +[10, ["number", -10], 614, 408, [14, null]], +[11, "pendown", 480, 147, [1, 5]], +[12, "setpensize", 20, 84, [27, 13, 52]], +[13, ["number", 1], 102, 84, [12, null]], +[14, ["plus2", 0], 573, 376, [8, 15, 10]], +[15, "ycor", 614, 376, [14, null]], +[16, ["plus2", 0], 573, 224, [8, 17, 24]], +[17, "xcor", 614, 224, [16, null]], +[18, ["random", 0], 696, 320, [23, 19, 20, null]], +[19, ["number", 0], 763, 320, [18, null]], +[20, ["number", 1], 763, 352, [18, null]], +[21, "stack1", 66, 472, [26, null]], +[22, "hat1", 480, 20, [null, 4]], +[23, ["plus2", 0], 655, 288, [24, 9, 18]], +[24, ["product2", 0], 614, 256, [16, 25, 23]], +[25, ["number", 20], 655, 256, [24, null]], +[26, "forever", 20, 458, [53, 21, null]], +[27, "clean", 20, 52, [0, 12]], +[28, ["number", -400.0], 64, 180, [50, null]], +[29, "repeat", 20, 243, [50, 30, 32, 31]], +[30, ["number", 80], 59, 243, [29, null]], +[31, ["vspace", 40], 20, 302, [29, 59]], +[32, ["storein", 0], 69, 288, [29, 58, 33, 54]], +[33, ["number", 0], 124, 320, [32, null]], +[34, ["storein", 0], 220, 52, [36, 43, 38, 41]], +[35, "stack2", 480, 390, [7, null]], +[36, "hat2", 220, 20, [null, 34]], +[37, "box", 316, 84, [38, 44, null]], +[38, ["plus2", 0], 275, 84, [34, 37, 39]], +[39, ["number", 1], 316, 116, [38, null]], +[40, "forward", 220, 179, [46, 42, 48]], +[41, ["vspace", 0], 220, 115, [34, 46]], +[42, "box", 274, 179, [40, 45, null]], +[43, "xcor", 275, 52, [34, null]], +[44, "xcor", 357, 84, [37, null]], +[45, "xcor", 315, 179, [42, null]], +[46, "setpensize", 220, 147, [41, 47, 40]], +[47, ["number", 18], 302, 147, [46, null]], +[48, "setpensize", 220, 211, [40, 49, null]], +[49, ["number", 1], 302, 211, [48, null]], +[50, ["setxy2", 0], 20, 180, [56, 28, 51, 29]], +[51, ["number", 0], 64, 212, [50, null]], +[52, "penup", 20, 116, [12, 56]], +[53, "pendown", 20, 426, [59, 26]], +[54, "forward", 69, 351, [32, 55, null]], +[55, ["number", 10.0], 123, 351, [54, null]], +[56, "seth", 20, 148, [52, 57, 50]], +[57, ["number", 90.0], 64, 148, [56, null]], +[58, "xcor", 124, 288, [32, null]], +[59, "seth", 20, 394, [31, 60, 53]], +[60, ["number", 0], 64, 394, [59, null]]] |