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-07-05 18:54:38 (GMT)
committer Walter Bender <walter.bender@gmail.com>2012-07-05 18:54:38 (GMT)
commit6c56adbc990b82b25256805cf683ef0dde5b28b8 (patch)
tree5e386c44c7e63979033aaf85a4e8cac478443325
parent4029ddcd1bf0da391fb26b7e717fe015bafb0fb9 (diff)
refactoring of sandwich blocks to use clamp
-rw-r--r--TurtleArt/tablock.py38
-rw-r--r--TurtleArt/taconstants.py10
-rw-r--r--TurtleArt/talogo.py3
-rw-r--r--TurtleArt/tapalette.py2
-rwxr-xr-xTurtleArt/tasprite_factory.py17
-rw-r--r--TurtleArt/tautils.py77
-rw-r--r--TurtleArt/tawindow.py48
-rw-r--r--plugins/turtle_blocks_extras/turtle_blocks_extras.py28
8 files changed, 192 insertions, 31 deletions
diff --git a/TurtleArt/tablock.py b/TurtleArt/tablock.py
index 7a8edf6..d9a6731 100644
--- a/TurtleArt/tablock.py
+++ b/TurtleArt/tablock.py
@@ -173,6 +173,8 @@ class Block:
'boolean-style': self._make_boolean_style,
'not-style': self._make_not_style,
'clamp-style': self._make_clamp_style,
+ 'clamp-style-collapsible': self._make_clamp_style_collapsible,
+ 'clamp-style-collapsed': self._make_clamp_style_collapsed,
'clamp-style-1arg': self._make_clamp_style_1arg,
'clamp-style-boolean': self._make_clamp_style_boolean,
'clamp-style-else': self._make_clamp_style_else,
@@ -254,12 +256,12 @@ class Block:
def highlight(self):
""" We may want to highlight a block... """
- if self.spr is not None:
+ if self.spr is not None and self.status is not 'collapsed':
self.spr.set_shape(self.shapes[1])
def unhighlight(self):
""" Or unhighlight it. """
- if self.spr is not None:
+ if self.spr is not None and self.status is not 'collapsed':
self.spr.set_shape(self.shapes[0])
def resize(self):
@@ -523,7 +525,8 @@ class Block:
def _calc_moving_labels(self, i):
''' Some labels move as blocks change shape/size '''
- if self.name in block_styles['clamp-style']:
+ if self.name in block_styles['clamp-style'] or \
+ self.name in block_styles['clamp-style-collapsible']:
y = int((self.docks[0][3] + self.docks[1][3]) / 3)
self.spr.set_label_attributes(int(self._font_size[0] + 0.5),
True, 'right', y_pos=y, i=0)
@@ -860,6 +863,31 @@ class Block:
['flow', False, self.svg.docks[3][0],
self.svg.docks[3][1], ']']]
+ def _make_clamp_style_collapsible(self, svg, extend_x=0, extend_y=4):
+ self.svg.expand(self.dx + self.ex + extend_x, self.ey + extend_y)
+ self.svg.set_slot(True)
+ self.svg.set_tab(True)
+ self.svg.set_collapsible(True)
+ self.svg.second_clamp(False)
+ self._make_block_graphics(svg, self.svg.clamp)
+ self.docks = [['flow', True, self.svg.docks[0][0],
+ self.svg.docks[0][1]],
+ ['flow', False, self.svg.docks[1][0],
+ self.svg.docks[1][1], '['],
+ # Skip bottom of clamp
+ ['flow', False, self.svg.docks[3][0],
+ self.svg.docks[3][1], ']']]
+
+ def _make_clamp_style_collapsed(self, svg, extend_x=0, extend_y=4):
+ self.svg.expand(self.dx + self.ex + extend_x, self.ey + extend_y)
+ self.svg.set_show(True)
+ self._make_block_graphics(svg, self.svg.basic_block)
+ self.docks = [['flow', True, self.svg.docks[0][0],
+ self.svg.docks[0][1]],
+ ['unavailable', True, 0, self.svg.docks[0][1] + 10, '['],
+ ['flow', False, self.svg.docks[1][0],
+ self.svg.docks[1][1], ']']]
+
def _make_clamp_style_1arg(self, svg, extend_x=0, extend_y=4):
self.svg.expand(self.dx + self.ex + extend_x, self.ey + extend_y)
self.svg.set_slot(True)
@@ -940,6 +968,8 @@ class Block:
self.svg.docks[0][1]], ['flow', False,
self.svg.docks[1][0], self.svg.docks[1][1]]]
+ # Depreciated block styles
+
def _make_invisible_style(self, svg):
self._make_block_graphics(svg, self.svg.invisible)
# force dock positions to be the same
@@ -947,8 +977,6 @@ class Block:
self.svg.docks[0][1]], ['flow', False,
self.svg.docks[0][0], self.svg.docks[0][1]]]
- # Depreciated block styles
-
def _make_flow_style(self, svg):
self.svg.expand(10 + self.dx + self.ex, self.ey)
self.svg.set_slot(True)
diff --git a/TurtleArt/taconstants.py b/TurtleArt/taconstants.py
index e246b03..92ce9eb 100644
--- a/TurtleArt/taconstants.py
+++ b/TurtleArt/taconstants.py
@@ -91,7 +91,8 @@ EXPANDABLE_STYLE = ['boolean-style', 'compare-porch-style', 'compare-style',
'number-style-block', 'box-style-media']
# Fixme: this should be based on styles
-EXPANDABLE_FLOW = ['repeat', 'until', 'while', 'if', 'forever', 'ifelse']
+EXPANDABLE_FLOW = ['repeat', 'until', 'while', 'if', 'forever', 'ifelse',
+ 'sandwichclamp']
EXPANDABLE = ['vspace', 'hspace', 'identity2']
@@ -99,6 +100,7 @@ EXPANDABLE_ARGS = ['list', 'myfunc1arg', 'myfunc2arg', 'myfunc3arg',
'userdefined', 'userdefined2args', 'userdefined3args']
#
# Blocks that are 'collapsible'
+# Deprecated
#
COLLAPSIBLE = ['sandwichbottom', 'sandwichcollapsed']
@@ -221,12 +223,8 @@ VOICES = {'af': 'afrikaans', 'cy': 'welsh-test', 'el': 'greek',
# Macros (groups of blocks)
#
MACROS = {
- 'ifthenelse':
+ 'ifthenelse': # Because it is too big to fit on the palette
[[0, 'ifelse', 0, 0, [None, None, None, None]]],
- 'clamp':
- [[0, 'sandwichtop_no_label', 0, 0, [None, 1]],
- [1, 'vspace', 0, 0, [0, 2]],
- [2, 'sandwichbottom', 0, 0, [1, None]]],
'kbinput':
[[0, 'until', 0, 0, [None, 1, 4, None]],
[1, 'greater2', 0, 0, [0, 2, 3, None]],
diff --git a/TurtleArt/talogo.py b/TurtleArt/talogo.py
index 3b55281..c422d29 100644
--- a/TurtleArt/talogo.py
+++ b/TurtleArt/talogo.py
@@ -386,7 +386,6 @@ class LogoCode:
# If the blocks are visible, highlight the current block.
if not self.tw.hide and self.bindex is not None:
self.tw.block_list.list[self.bindex].highlight()
-
# In debugging modes, we pause between steps and show the turtle.
if self.tw.step_time > 0:
self.tw.active_turtle.show()
@@ -408,12 +407,10 @@ class LogoCode:
# Time to unhighlight the current block.
if not self.tw.hide and self.bindex is not None:
self.tw.block_list.list[self.bindex].unhighlight()
-
if self.procstop:
break
if self.iresult == None:
continue
-
if self.bindex is not None:
self.tw.block_list.list[self.bindex].highlight()
self.tw.showblocks()
diff --git a/TurtleArt/tapalette.py b/TurtleArt/tapalette.py
index 0b7d740..72533e8 100644
--- a/TurtleArt/tapalette.py
+++ b/TurtleArt/tapalette.py
@@ -70,6 +70,8 @@ block_styles = {'basic-style': [],
'flow-style-while': [],
'flow-style-else': [],
'clamp-style': [],
+ 'clamp-style-collapsible': [],
+ 'clamp-style-collapsed': [],
'clamp-style-1arg': [],
'clamp-style-boolean': [],
'clamp-style-else': [],
diff --git a/TurtleArt/tasprite_factory.py b/TurtleArt/tasprite_factory.py
index 6f31379..a34516a 100755
--- a/TurtleArt/tasprite_factory.py
+++ b/TurtleArt/tasprite_factory.py
@@ -73,6 +73,7 @@ class SVG:
self._draw_innies = True
self._hide = False
self._show = False
+ self._collapsible = False
self._show_x = 0
self._show_y = 0
self._hide_x = 0
@@ -162,6 +163,8 @@ class SVG:
self.style()
return self.header() + self.footer()
+ # Deprecated
+
def basic_flow(self):
''' A flow block includes an arm that holds a branch in the flow '''
self.reset_min_max()
@@ -569,6 +572,8 @@ class SVG:
svg += self._close_path()
self.calc_w_h()
svg += self.style()
+ if self._collapsible:
+ svg += self._hide_dot()
svg += self.footer()
return self.header() + svg
@@ -685,6 +690,9 @@ class SVG:
def set_show(self, flag=False):
self._show = flag
+ def set_collapsible(self, flag=False):
+ self._collapsible = flag
+
def get_width(self):
return self._width
@@ -706,8 +714,8 @@ class SVG:
def set_orientation(self, orientation=0):
self._orientation = orientation
- def second_clamp(self, arg=False):
- self._second_clamp = arg
+ def second_clamp(self, flag=False):
+ self._second_clamp = flag
def expand(self, w=0, h=0, w2=0, h2=0):
self._expand_x = w
@@ -1245,11 +1253,12 @@ def close_file(f):
def generator(datapath):
svg0 = SVG()
- f = open_file(datapath, "clamp")
+ f = open_file(datapath, "clamp.svg")
svg0.set_scale(2)
svg0.set_arm(True)
svg0.expand(0, 0, 0, 21)
- svg0.second_clamp(True)
+ svg0.set_collapsible(True)
+ svg0.set_hide(True)
svg_str = svg0.clamp()
f.write(svg_str)
close_file(f)
diff --git a/TurtleArt/tautils.py b/TurtleArt/tautils.py
index 6871f35..dcbcf65 100644
--- a/TurtleArt/tautils.py
+++ b/TurtleArt/tautils.py
@@ -396,7 +396,81 @@ def calc_image_size(spr):
int(max(spr.label_safe_height(), 1))
-# Collapsible stacks live between 'sandwichtop' and 'sandwichbottom' blocks
+def restore_clamp(top):
+ ''' Restore the blocks in a sandwich clamp. '''
+ if top is None:
+ return
+
+ if top.name == 'sandwichclampcollapsed':
+ y1 = top.docks[2][3]
+ if top.connections[1] is not None:
+ for blk in find_group(top.connections[1]):
+ blk.spr.restore()
+ blk.status = None
+
+ # If you come across a 'sandwichclampcollapsed', do not
+ # restore its clamp
+ for blk in find_group(top.connections[1]):
+ if blk.name == 'sandwichclampcollapsed':
+ if blk.connections[1] is not None:
+ for b in find_group(blk.connections[1]):
+ b.spr.hide()
+ b.status = 'collapsed'
+
+ bot = top.connections[2]
+ top.name = 'sandwichclamp'
+ top.spr.set_label('')
+ top.resize()
+ top.svg.set_hide(True)
+ top.refresh()
+ y2 = top.docks[2][3]
+ dy = y2 - y1
+ if bot is not None:
+ for blk in find_group(bot):
+ blk.spr.move_relative((0, dy))
+ if top.connections[1] is not None:
+ # Make sure stack is aligned to dock
+ x1, y1 = top.connections[1].spr.get_xy()
+ x1 += top.connections[1].docks[0][2]
+ y1 += top.connections[1].docks[0][3]
+ x2, y2 = top.spr.get_xy()
+ x2 += top.docks[1][2]
+ y2 += top.docks[1][3]
+ if x1 != x2 or y1 != y2:
+ for blk in find_group(top.connections[1]):
+ blk.spr.move_relative((x2 - x1, y2 - y1))
+ return
+
+
+def collapse_clamp(top, transform=True):
+ ''' Hide all the blocks in the clamp. '''
+ if top == None or top.spr == None:
+ return
+
+ if top.name in ['sandwichclampcollapsed', 'sandwichclamp']:
+ y1 = top.docks[2][3]
+ if top.connections[1] is not None:
+ for blk in find_group(top.connections[1]):
+ blk.spr.hide()
+ blk.status = 'collapsed'
+ if transform:
+ bot = top.connections[2]
+ top.name = 'sandwichclampcollapsed'
+ top.spr.set_label(_('click to open'))
+ top.reset_y()
+ top.resize()
+ top.svg.set_hide(False)
+ top.refresh()
+ y2 = top.docks[2][3]
+ dy = y2 - y1
+ if bot is not None:
+ for blk in find_group(bot):
+ blk.spr.move_relative((0, dy))
+ return
+
+
+# Deprecated: Collapsible stacks live between 'sandwichtop' and
+# 'sandwichbottom' blocks
def reset_stack_arm(top):
@@ -555,6 +629,7 @@ def collapse_stack(top):
# First uncollapse any nested stacks
if top == None or top.spr == None:
return
+
uncollapse_forks(top)
hit_bottom = False
bot = find_sandwich_bottom(top)
diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py
index 43851ab..31e8f6a 100644
--- a/TurtleArt/tawindow.py
+++ b/TurtleArt/tawindow.py
@@ -69,7 +69,7 @@ from tautils import magnitude, get_load_name, get_save_name, data_from_file, \
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, convert, \
- find_bot_block
+ find_bot_block, restore_clamp, collapse_clamp
from tasprite_factory import SVG, svg_str_to_pixbuf, svg_from_file
from sprites import Sprites, Sprite
@@ -727,6 +727,7 @@ class TurtleArtWindow():
# We need to restore collapsed stacks before resizing.
for blk in blocks:
+ # Deprecated
if blk.status == 'collapsed':
bot = find_sandwich_bottom(blk)
if collapsed(bot):
@@ -740,6 +741,7 @@ class TurtleArtWindow():
for blk in blocks:
self._adjust_dock_positions(blk)
+ # Deprecated
# Re-collapsed stacks after resizing.
for blk in blocks:
if collapsed(blk):
@@ -834,6 +836,7 @@ class TurtleArtWindow():
blk.spr.hide()
if n == palette_names.index('trash'):
for blk in self.trash_stack:
+ # Deprecated
for gblk in find_group(blk):
if gblk.status != 'collapsed':
gblk.spr.set_layer(TAB_LAYER)
@@ -1540,6 +1543,7 @@ class TurtleArtWindow():
self.trash_stack.append(blk)
group = find_group(blk)
for gblk in group:
+ # Deprecated
if gblk.status == 'collapsed':
# Collapsed stacks are restored for rescaling
# and then recollapsed after they are moved to the trash.
@@ -1554,6 +1558,7 @@ class TurtleArtWindow():
for gblk in group:
self._adjust_dock_positions(gblk)
+ # Deprecated
# Re-collapsing any stacks we had restored for scaling
for gblk in group:
if collapsed(gblk):
@@ -1620,6 +1625,7 @@ class TurtleArtWindow():
gblk.type = 'block'
for gblk in group:
self._adjust_dock_positions(gblk)
+ # Deprecated
# If the stack had been collapsed before going into the trash,
# collapse it again now.
for gblk in group:
@@ -1779,6 +1785,7 @@ class TurtleArtWindow():
macro[0][3] = y
top = self.process_data(macro)
self.block_operation = 'new'
+ # Deprecated
self._check_collapsibles(top)
self.drag_group = find_group(top)
@@ -1868,6 +1875,10 @@ class TurtleArtWindow():
# Look for any stacks that need to be collapsed or sandwiched
for blk in blocks:
+ if blk.name == 'sandwichclampcollapsed':
+ collapse_clamp(blk, False)
+
+ # Deprecated
if collapsed(blk):
collapse_stack(find_sandwich_top(blk))
elif blk.name == 'sandwichbottom' and collapsible(blk):
@@ -1988,6 +1999,7 @@ class TurtleArtWindow():
elif self.drag_group[0] is not None:
blk = self.drag_group[0]
+ # Deprecated
# Don't move a bottom blk if the stack is collapsed
if collapsed(blk):
return
@@ -2369,13 +2381,24 @@ class TurtleArtWindow():
self._import_py()
else:
self._run_stack(blk)
-
- elif blk.name in ['sandwichtop_no_arm_no_label',
- 'sandwichtop_no_arm']:
+ elif blk.name == 'sandwichclampcollapsed':
+ restore_clamp(blk)
+ if blk.connections[1] is not None:
+ self._resize_clamp(blk, blk.connections[1], 1)
+ self._resize_parent_clamps(blk)
+ elif blk.name == 'sandwichclamp':
+ if hide_button_hit(blk.spr, x, y):
+ collapse_clamp(blk, True)
+ self._resize_parent_clamps(blk)
+ else:
+ self._run_stack(blk)
+ # Deprecated
+ elif blk.name in ['sandwichclampcollapsed',
+ 'sandwichtop_no_arm_no_label', 'sandwichtop_no_arm']:
restore_stack(blk)
-
- elif blk.name in COLLAPSIBLE or blk.name == 'sandwichtop_no_label':
- if blk.name == 'sandwichtop_no_label':
+ # Deprecated
+ elif blk.name in COLLAPSIBLE or blk.name in ['sandwichtop_no_label']:
+ if blk.name in ['sandwichtop_no_label']:
if hide_button_hit(blk.spr, x, y):
collapse_stack(blk)
else:
@@ -2388,6 +2411,13 @@ class TurtleArtWindow():
else:
self._run_stack(blk)
+ def _resize_parent_clamps(self, blk):
+ ''' If we changed size, we need to let any parent clamps know. '''
+ nblk, dockn = self._expandable_flow_above(blk)
+ while nblk is not None:
+ self._resize_clamp(nblk, nblk.connections[dockn], dockn=dockn)
+ nblk, dockn = self._expandable_flow_above(nblk)
+
def _expand_boolean(self, blk, blk2, dy):
''' Expand a boolean blk if blk2 is too big to fit. '''
group = find_group(blk2)
@@ -2450,6 +2480,7 @@ class TurtleArtWindow():
else:
break
+ # Deprecated
def _check_collapsibles(self, blk):
''' Check state of collapsible blocks upon change in dock state. '''
group = find_group(blk)
@@ -3037,6 +3068,7 @@ class TurtleArtWindow():
''' Jog block '''
if blk.type == 'proto':
return
+ # Deprecated
if collapsed(blk):
return
if dx == 0 and dy == 0:
@@ -3226,6 +3258,7 @@ class TurtleArtWindow():
''' Load a project from a file '''
if create_new_project:
self.new_project()
+ # Deprecated
self._check_collapsibles(self.process_data(data_from_file(ta_file)))
self._loaded_project = ta_file
@@ -3328,6 +3361,7 @@ class TurtleArtWindow():
values = [round_int(value)]
except ValueError:
values = [0]
+ # Deprecated
elif btype in COLLAPSIBLE:
if value is not None:
values = [int(value)]
diff --git a/plugins/turtle_blocks_extras/turtle_blocks_extras.py b/plugins/turtle_blocks_extras/turtle_blocks_extras.py
index 7a9fc03..f904f67 100644
--- a/plugins/turtle_blocks_extras/turtle_blocks_extras.py
+++ b/plugins/turtle_blocks_extras/turtle_blocks_extras.py
@@ -675,13 +675,24 @@ module found in the Journal'))
label=_('turtle shell'),
help_string=_("put a custom 'shell' on the turtle"))
- # macro
- palette.add_block('clamp',
- style='collapsible-top-no-label',
- label=[' ', ' '],
+ primitive_dictionary['clamp'] = self._prim_clamp
+ palette.add_block('sandwichclamp',
+ style='clamp-style-collapsible',
+ label=' ',
+ special_name=_('top'),
+ prim_name='clamp',
+ help_string=_('top of a collapsible stack'))
+ self.tw.lc.def_prim('clamp', 1, primitive_dictionary['clamp'], True)
+
+ palette.add_block('sandwichclampcollapsed',
+ hidden=True,
+ style='clamp-style-collapsed',
+ label=_('click to open'),
+ prim_name='clamp',
special_name=_('top'),
help_string=_('top of a collapsed stack'))
+ # deprecated blocks
palette.add_block('sandwichtop_no_label',
hidden=True,
style='collapsible-top-no-label',
@@ -706,7 +717,6 @@ module found in the Journal'))
prim_name='nop',
help_string=_('collapsed stack: click to open'))
- # deprecated blocks
palette.add_block('sandwichcollapsed',
hidden=True,
colors=["#FF0000", "#A00000"],
@@ -1443,6 +1453,14 @@ bullets'))
self.tw.lc.stop_logo()
raise logoerror("#notanumber")
+ def _prim_clamp(self, blklist):
+ """ Run clamp blklist """
+ self.tw.lc.icall(self.tw.lc.evline, blklist[:])
+ yield True
+ self.tw.lc.procstop = False
+ self.tw.lc.ireturn()
+ yield True
+
# Deprecated blocks
def _prim_t1x1(self, title, media):