Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TurtleArt/tawindow.py138
-rw-r--r--samples/math-galton-path.ta118
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]]]