Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWalter Bender <walter.bender@gmail.com>2012-06-18 19:51:43 (GMT)
committer Walter Bender <walter.bender@gmail.com>2012-06-18 19:51:43 (GMT)
commit793b4cfa0bba78d0c7bc60cc24311135b49e3ef9 (patch)
tree5bc95ff3c6b8e8c4e53881467179d008dba7dd94
parent7e6809a54ae3d29c363cd82cbaf2e6dd7ba592e4 (diff)
add back in call to reload challenge after erase
-rw-r--r--TurtleArt/tawindow.py316
1 files changed, 284 insertions, 32 deletions
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. """