Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TurtleArt/tabasics.py40
-rw-r--r--TurtleArt/tablock.py241
-rw-r--r--TurtleArt/taconstants.py5
-rw-r--r--TurtleArt/tapalette.py4
-rw-r--r--TurtleArt/tawindow.py174
-rw-r--r--plugins/turtle_blocks_extras/turtle_blocks_extras.py12
6 files changed, 363 insertions, 113 deletions
diff --git a/TurtleArt/tabasics.py b/TurtleArt/tabasics.py
index 0fb0996..df9d186 100644
--- a/TurtleArt/tabasics.py
+++ b/TurtleArt/tabasics.py
@@ -733,10 +733,12 @@ number of seconds'))
primitive_dictionary['forever'] = self._prim_forever
palette.add_block('forever',
- style='flow-style',
+ # style='flow-style',
+ style='clamp-style',
label=_('forever'),
prim_name='forever',
- default=[None, 'vspace'],
+ # default=[None, 'vspace'],
+ default=[None, None],
logo_command='forever',
help_string=_('loops forever'))
self.tw.lc.def_prim('forever', 1, primitive_dictionary['forever'],
@@ -744,10 +746,12 @@ number of seconds'))
primitive_dictionary['repeat'] = self._prim_repeat
palette.add_block('repeat',
- style='flow-style-1arg',
- label=['', _('repeat')],
+ # style='flow-style-1arg',
+ style='clamp-style-1arg',
+ label=_('repeat'),
prim_name='repeat',
- default=[4, None, 'vspace'],
+ # default=[4, None, 'vspace'],
+ default=[4, None, None],
logo_command='repeat',
special_name=_('repeat'),
help_string=_('loops specified number of times'))
@@ -755,10 +759,13 @@ number of seconds'))
primitive_dictionary['if'] = self._prim_if
palette.add_block('if',
- style='flow-style-boolean',
- label=[_('if'), '', _('then')],
+ # style='flow-style-boolean',
+ style='clamp-style-boolean',
+ # label=[_('if'), '', _('then')],
+ label=[_('if'), _('then'), ''],
prim_name='if',
- default=[None, None, 'vspace'],
+ # default=[None, None, 'vspace'],
+ default=[None, None, None],
special_name=_('if then'),
logo_command='if',
help_string=_('if-then operator that uses boolean \
@@ -767,18 +774,29 @@ operators from Numbers palette'))
primitive_dictionary['ifelse'] = self._prim_ifelse
palette.add_block('ifelse',
- style='flow-style-else',
- label=[_('if'), '', _('then else')],
+ hidden=True, # Too big to fit palette
+ # style='flow-style-else',
+ style='clamp-style-else',
+ label=[_('if'), _('then'), _('else')],
prim_name='ifelse',
- default=[None, 'vspace', None, 'vspace'],
+ # default=[None, 'vspace', None, 'vspace'],
+ default=[None, None, None, None],
logo_command='ifelse',
special_name=_('if then else'),
help_string=_('if-then-else operator that uses \
boolean operators from Numbers palette'))
self.tw.lc.def_prim('ifelse', 3, primitive_dictionary['ifelse'], True)
+ # macro
+ palette.add_block('ifthenelse',
+ style='basic-style-extended-vertical',
+ label=_('if then else'),
+ help_string=_('if-then-else operator that uses \
+boolean operators from Numbers palette'))
+
palette.add_block('hspace',
style='flow-style-tail',
+ hidden=True,
label='',
prim_name='nop',
special_name=_('horizontal space'),
diff --git a/TurtleArt/tablock.py b/TurtleArt/tablock.py
index f835994..7a8edf6 100644
--- a/TurtleArt/tablock.py
+++ b/TurtleArt/tablock.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-#Copyright (c) 2010,11 Walter Bender
+#Copyright (c) 2010-2012 Walter Bender
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,8 @@ import gtk
from gettext import gettext as _
from taconstants import EXPANDABLE, EXPANDABLE_ARGS, OLD_NAMES, CONSTANTS, \
- STANDARD_STROKE_WIDTH, BLOCK_SCALE, BOX_COLORS, GRADIENT_COLOR
+ STANDARD_STROKE_WIDTH, BLOCK_SCALE, BOX_COLORS, GRADIENT_COLOR, \
+ EXPANDABLE_FLOW
from tapalette import palette_blocks, block_colors, expandable_blocks, \
content_blocks, block_names, block_primitives, block_styles, \
special_block_colors
@@ -139,6 +140,7 @@ class Block:
self.dx = 0
self.ex = 0
self.ey = 0
+ self.ey2 = 0
self._ei = 0
self._font_size = [6.0, 4.5]
self._image = None
@@ -170,11 +172,10 @@ class Block:
'compare-porch-style': self._make_compare_porch_style,
'boolean-style': self._make_boolean_style,
'not-style': self._make_not_style,
- 'flow-style': self._make_flow_style,
- 'flow-style-tail': self._make_flow_style_tail,
- 'flow-style-1arg': self._make_flow_style_1arg,
- 'flow-style-boolean': self._make_flow_style_boolean,
- 'flow-style-else': self._make_flow_style_else,
+ 'clamp-style': self._make_clamp_style,
+ 'clamp-style-1arg': self._make_clamp_style_1arg,
+ 'clamp-style-boolean': self._make_clamp_style_boolean,
+ 'clamp-style-else': self._make_clamp_style_else,
'collapsible-top': [self._make_collapsible_style_top, True, True],
'collapsible-top-no-arm': [self._make_collapsible_style_top,
False, True],
@@ -183,6 +184,11 @@ class Block:
'collapsible-top-no-arm-no-label': [
self._make_collapsible_style_top, False, False],
'collapsible-bottom': self._make_collapsible_style_bottom,
+ 'flow-style': self._make_flow_style,
+ 'flow-style-tail': self._make_flow_style_tail,
+ 'flow-style-1arg': self._make_flow_style_1arg,
+ 'flow-style-boolean': self._make_flow_style_boolean,
+ 'flow-style-else': self._make_flow_style_else,
'portfolio-style-2x2': self._make_portfolio_style_2x2,
'portfolio-style-1x1': self._make_portfolio_style_1x1,
'portfolio-style-2x1': self._make_portfolio_style_2x1,
@@ -232,6 +238,8 @@ class Block:
return True
if self.name in EXPANDABLE_ARGS:
return True
+ if self.name in EXPANDABLE_FLOW:
+ return True
return False
def cloneable(self):
@@ -290,7 +298,6 @@ class Block:
self.scale = scale
for i in range(len(self._font_size)):
self._font_size[i] *= self.scale
- self._set_label_attributes()
self.svg.set_scale(self.scale)
self.refresh()
self.spr.inval()
@@ -305,6 +312,7 @@ class Block:
return
self._make_block(self.svg)
self._set_margins()
+ self._set_label_attributes()
self.spr.set_shape(self.shapes[0])
def add_arg(self, keep_expanding=True):
@@ -336,6 +344,22 @@ class Block:
self.svg.set_show(False)
self.refresh()
+ def expand_in_y2(self, dy):
+ """ We may want to grow a block vertically. """
+ if self.spr is None:
+ return
+ self.ey2 += dy
+ if self.type == 'block':
+ if self.ey2 > 0:
+ self.svg.set_hide(True)
+ else:
+ self.svg.set_hide(False)
+ self.svg.set_show(True)
+ else:
+ self.svg.set_hide(False)
+ self.svg.set_show(False)
+ self.refresh()
+
def expand_in_x(self, dx):
""" We may want to grow a block horizontally. """
if self.spr is None:
@@ -375,10 +399,23 @@ class Block:
self.refresh()
return dy
+ def reset_y2(self):
+ if self.spr is None:
+ return 0
+ dy = -self.ey2
+ self.ey2 = 0
+ self.svg.set_hide(False)
+ if self.type == 'block':
+ self.svg.set_show(True)
+ else: # 'proto'
+ self.svg.set_show(False)
+ self.refresh()
+ return dy
+
def get_expand_x_y(self):
if self.spr is None:
return(0, 0)
- return (self.ex, self.ey)
+ return (self.ex, self.ey, self.ey2)
def _new_block_from_factory(self, sprite_list, x, y, copy_block=None):
self.svg = SVG()
@@ -459,28 +496,59 @@ class Block:
for i in range(n):
if self.name in block_styles['compare-porch-style']:
self.spr.set_label_attributes(int(self._font_size[0] + 0.5),
- True, 'center', 'bottom', i)
+ True, 'center', 'bottom', i=i)
elif self.name in block_styles['number-style-porch']:
self.spr.set_label_attributes(int(self._font_size[0] + 0.5),
- True, 'right', 'bottom', i)
-
+ True, 'right', 'bottom', i=i)
+ elif self.name in EXPANDABLE_FLOW:
+ self._calc_moving_labels(i)
+ # Deprecated
elif self.name in block_styles['flow-style-boolean'] or \
self.name in block_styles['flow-style-else']:
self.spr.set_label_attributes(int(self._font_size[0] + 0.5),
- True, 'left', 'middle', 0)
+ True, 'left', 'middle', i=0)
self.spr.set_label_attributes(int(self._font_size[1] + 0.5),
- True, 'right', 'top', 1)
+ True, 'right', 'top', i=1)
self.spr.set_label_attributes(int(self._font_size[1] + 0.5),
- True, 'right', 'bottom', 2)
+ True, 'right', 'bottom', i=2)
elif i == 1: # top
self.spr.set_label_attributes(int(self._font_size[1] + 0.5),
- True, 'right', 'top', i)
+ True, 'right', 'top', i=i)
elif i == 2: # bottom
self.spr.set_label_attributes(int(self._font_size[1] + 0.5),
- True, 'right', 'bottom', i)
+ True, 'right', 'bottom', i=i)
else:
self.spr.set_label_attributes(int(self._font_size[0] + 0.5),
- True, 'center', 'middle', i)
+ True, 'center', 'middle', i=i)
+
+ def _calc_moving_labels(self, i):
+ ''' Some labels move as blocks change shape/size '''
+ if self.name in block_styles['clamp-style']:
+ 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)
+ elif self.name in block_styles['clamp-style-1arg']:
+ y = self.docks[1][3] - int(int(self._font_size[0] * 1.3))
+ self.spr.set_label_attributes(int(self._font_size[0] + 0.5),
+ True, 'right', y_pos=y, i=0)
+ elif self.name in block_styles['clamp-style-boolean']:
+ y = self.docks[1][3] - int(int(self._font_size[0] * 1.3))
+ self.spr.set_label_attributes(int(self._font_size[0] + 0.5),
+ True, 'right', y_pos=y, i=0)
+ y = self.docks[2][3] - int(int(self._font_size[0] * 1.3))
+ self.spr.set_label_attributes(int(self._font_size[1] + 0.5),
+ True, 'right', y_pos=y, i=1)
+ elif self.name in block_styles['clamp-style-else']:
+ y = self.docks[1][3] - int(int(self._font_size[0] * 1.3))
+ self.spr.set_label_attributes(int(self._font_size[0] + 0.5),
+ True, 'right', y_pos=y, i=0)
+ y = self.docks[2][3] - int(int(self._font_size[0] * 1.3))
+ self.spr.set_label_attributes(int(self._font_size[1] + 0.5),
+ True, 'right', y_pos=y, i=1)
+ y = self.docks[3][3] - int(int(self._font_size[0] * 1.3))
+ self.spr.set_label_attributes(int(self._font_size[1] + 0.5),
+ True, 'right', y_pos=y, i=2)
+
def _set_labels(self, i, label):
if self.spr is None:
@@ -778,75 +846,74 @@ class Block:
['bool', False, self.svg.docks[1][0],
self.svg.docks[1][1]]]
- def _make_flow_style(self, svg):
- self.svg.expand(10 + self.dx + self.ex, self.ey)
+ def _make_clamp_style(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._make_block_graphics(svg, self.svg.basic_flow)
+ 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], '['],
- ['flow', False, self.svg.docks[2][0],
- self.svg.docks[2][1], ']']]
-
- def _make_flow_style_tail(self, svg):
- self.svg.expand(10 + self.dx + self.ex, self.ey)
- self.svg.set_slot(True)
- self.svg.set_tab(False)
- self._make_block_graphics(svg, self.svg.basic_flow)
- 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_flow_style_1arg(self, svg):
- self.svg.expand(self.dx + self.ex, self.ey)
+ 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)
self.svg.set_tab(True)
self.svg.set_innie([True])
- self._make_block_graphics(svg, self.svg.basic_flow)
+ 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]],
['number', False, self.svg.docks[1][0],
self.svg.docks[1][1]],
['flow', False, self.svg.docks[2][0],
self.svg.docks[2][1], '['],
- ['flow', False, self.svg.docks[3][0],
- self.svg.docks[3][1], ']']]
+ # Skip bottom of clamp
+ ['flow', False, self.svg.docks[4][0],
+ self.svg.docks[4][1], ']']]
- def _make_flow_style_boolean(self, svg):
- self.svg.expand(self.dx + self.ex, self.ey)
+ def _make_clamp_style_boolean(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_boolean(True)
- self._make_block_graphics(svg, self.svg.basic_flow)
+ 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]],
['bool', False, self.svg.docks[1][0],
- self.svg.docks[1][1]],
+ self.svg.docks[1][1]],
['flow', False, self.svg.docks[2][0],
self.svg.docks[2][1], '['],
- ['flow', False, self.svg.docks[3][0],
- self.svg.docks[3][1], ']']]
+ # Skip bottom of clamp
+ ['flow', False, self.svg.docks[4][0],
+ self.svg.docks[4][1], ']']]
- def _make_flow_style_else(self, svg):
- self.svg.expand(self.dx + self.ex, self.ey)
+ def _make_clamp_style_else(self, svg, extend_x=0, extend_y=4):
+ self.svg.expand(self.dx + self.ex + extend_x, self.ey + extend_y,
+ self.dx + self.ex + extend_x, self.ey2 + extend_y)
self.svg.set_slot(True)
self.svg.set_tab(True)
- self.svg.set_else(True)
self.svg.set_boolean(True)
- self._make_block_graphics(svg, self.svg.basic_flow)
+ self.svg.second_clamp(True)
+ self._make_block_graphics(svg, self.svg.clamp)
self.docks = [['flow', True, self.svg.docks[0][0],
self.svg.docks[0][1]],
['bool', False, self.svg.docks[1][0],
self.svg.docks[1][1]],
- ['flow', False, self.svg.docks[3][0],
- self.svg.docks[3][1], '['],
['flow', False, self.svg.docks[2][0],
- self.svg.docks[2][1], ']['],
+ self.svg.docks[2][1], '['],
+ # Skip bottom of clamp
['flow', False, self.svg.docks[4][0],
- self.svg.docks[4][1], ']']]
+ self.svg.docks[4][1], ']['],
+ # Skip bottom of clamp
+ ['flow', False, self.svg.docks[6][0],
+ self.svg.docks[6][1], ']']]
def _make_collapsible_style_top(self, svg, arm=True, label=True):
self.svg.expand(self.dx + self.ex, self.ey)
@@ -882,6 +949,76 @@ class Block:
# Depreciated block styles
+ def _make_flow_style(self, svg):
+ self.svg.expand(10 + self.dx + self.ex, self.ey)
+ self.svg.set_slot(True)
+ self.svg.set_tab(True)
+ self._make_block_graphics(svg, self.svg.basic_flow)
+ 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], '['],
+ ['flow', False, self.svg.docks[2][0],
+ self.svg.docks[2][1], ']']]
+
+ def _make_flow_style_tail(self, svg):
+ self.svg.expand(10 + self.dx + self.ex, self.ey)
+ self.svg.set_slot(True)
+ self.svg.set_tab(False)
+ self._make_block_graphics(svg, self.svg.basic_flow)
+ 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]]]
+
+ def _make_flow_style_1arg(self, svg):
+ self.svg.expand(self.dx + self.ex, self.ey)
+ self.svg.set_slot(True)
+ self.svg.set_tab(True)
+ self.svg.set_innie([True])
+ self._make_block_graphics(svg, self.svg.basic_flow)
+ self.docks = [['flow', True, self.svg.docks[0][0],
+ self.svg.docks[0][1]],
+ ['number', False, self.svg.docks[1][0],
+ self.svg.docks[1][1]],
+ ['flow', False, self.svg.docks[2][0],
+ self.svg.docks[2][1], '['],
+ ['flow', False, self.svg.docks[3][0],
+ self.svg.docks[3][1], ']']]
+
+ def _make_flow_style_boolean(self, svg):
+ self.svg.expand(self.dx + self.ex, self.ey)
+ self.svg.set_slot(True)
+ self.svg.set_tab(True)
+ self.svg.set_boolean(True)
+ self._make_block_graphics(svg, self.svg.basic_flow)
+ self.docks = [['flow', True, self.svg.docks[0][0],
+ self.svg.docks[0][1]],
+ ['bool', False, self.svg.docks[1][0],
+ self.svg.docks[1][1]],
+ ['flow', False, self.svg.docks[2][0],
+ self.svg.docks[2][1], '['],
+ ['flow', False, self.svg.docks[3][0],
+ self.svg.docks[3][1], ']']]
+
+ def _make_flow_style_else(self, svg):
+ self.svg.expand(self.dx + self.ex, self.ey)
+ self.svg.set_slot(True)
+ self.svg.set_tab(True)
+ self.svg.set_else(True)
+ self.svg.set_boolean(True)
+ self._make_block_graphics(svg, self.svg.basic_flow)
+ self.docks = [['flow', True, self.svg.docks[0][0],
+ self.svg.docks[0][1]],
+ ['bool', False, self.svg.docks[1][0],
+ self.svg.docks[1][1]],
+ ['flow', False, self.svg.docks[3][0],
+ self.svg.docks[3][1], '['],
+ ['flow', False, self.svg.docks[2][0],
+ self.svg.docks[2][1], ']['],
+ ['flow', False, self.svg.docks[4][0],
+ self.svg.docks[4][1], ']']]
+
def _make_portfolio_style_2x2(self, svg):
self.svg.expand(30 + self.dx + self.ex, 10 + self.ey)
self.svg.set_slot(True)
diff --git a/TurtleArt/taconstants.py b/TurtleArt/taconstants.py
index 0285f7b..e246b03 100644
--- a/TurtleArt/taconstants.py
+++ b/TurtleArt/taconstants.py
@@ -90,6 +90,9 @@ EXPANDABLE_STYLE = ['boolean-style', 'compare-porch-style', 'compare-style',
'number-style-porch', 'number-style', 'basic-style-2arg',
'number-style-block', 'box-style-media']
+# Fixme: this should be based on styles
+EXPANDABLE_FLOW = ['repeat', 'until', 'while', 'if', 'forever', 'ifelse']
+
EXPANDABLE = ['vspace', 'hspace', 'identity2']
EXPANDABLE_ARGS = ['list', 'myfunc1arg', 'myfunc2arg', 'myfunc3arg',
@@ -218,6 +221,8 @@ VOICES = {'af': 'afrikaans', 'cy': 'welsh-test', 'el': 'greek',
# Macros (groups of blocks)
#
MACROS = {
+ 'ifthenelse':
+ [[0, 'ifelse', 0, 0, [None, None, None, None]]],
'clamp':
[[0, 'sandwichtop_no_label', 0, 0, [None, 1]],
[1, 'vspace', 0, 0, [0, 2]],
diff --git a/TurtleArt/tapalette.py b/TurtleArt/tapalette.py
index 2af8ff1..0b7d740 100644
--- a/TurtleArt/tapalette.py
+++ b/TurtleArt/tapalette.py
@@ -69,6 +69,10 @@ block_styles = {'basic-style': [],
'flow-style-boolean': [],
'flow-style-while': [],
'flow-style-else': [],
+ 'clamp-style': [],
+ 'clamp-style-1arg': [],
+ 'clamp-style-boolean': [],
+ 'clamp-style-else': [],
'collapsible-top': [],
'collapsible-top-no-arm': [],
'collapsible-top-no-label': [],
diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py
index 4d766ec..43851ab 100644
--- a/TurtleArt/tawindow.py
+++ b/TurtleArt/tawindow.py
@@ -51,7 +51,7 @@ from taconstants import HORIZONTAL_PALETTE, VERTICAL_PALETTE, BLOCK_SCALE, \
CURSOR, EXPANDABLE, COLLAPSIBLE, DEAD_DICTS, DEAD_KEYS, NO_IMPORT, \
TEMPLATES, PYTHON_SKIN, PALETTE_HEIGHT, STATUS_LAYER, OLD_DOCK, \
EXPANDABLE_ARGS, XO1, XO15, XO175, XO30, TITLEXY, CONTENT_ARGS, \
- CONSTANTS, EXPAND_SKIN, PROTO_LAYER
+ CONSTANTS, EXPAND_SKIN, PROTO_LAYER, EXPANDABLE_FLOW
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, \
@@ -1409,7 +1409,6 @@ class TurtleArtWindow():
blk.spr.labels[0] = name
blk.values[0] = name
blk.spr.set_layer(BLOCK_LAYER)
- debug_output('update action names: calling change proto name', True)
self._update_proto_name(name, 'stack_%s' % (self._saved_action_name),
'stack_%s' % (name), 'basic-style-1arg')
@@ -1588,7 +1587,6 @@ class TurtleArtWindow():
palette_blocks[i].remove(name)
for blk in self.palettes[i]:
if blk.name == name:
- debug_output('removing blk from palette', True)
blk.spr.hide()
self.palettes[i].remove(blk)
self.show_toolbar_palette(i, regenerate=True)
@@ -2592,6 +2590,21 @@ class TurtleArtWindow():
dy += 45
best_destination.expand_in_y(dy)
self._expand_boolean(best_destination, selected_block, dy)
+ elif best_destination.name in EXPANDABLE_FLOW:
+ if best_destination.name in block_styles['clamp-style-1arg'] or\
+ best_destination.name in block_styles['clamp-style-boolean']:
+ if best_destination_dockn == 2:
+ self._resize_clamp(best_destination, self.drag_group[0])
+ elif best_destination.name in block_styles['clamp-style']:
+ if best_destination_dockn == 1:
+ self._resize_clamp(best_destination, self.drag_group[0])
+ elif best_destination.name in block_styles['clamp-style-else']:
+ if best_destination_dockn == 2:
+ self._resize_clamp(
+ best_destination, self.drag_group[0], dockn=2)
+ elif best_destination_dockn == 3:
+ self._resize_clamp(
+ best_destination, self.drag_group[0], dockn=3)
elif best_destination.name in expandable_blocks and \
best_destination_dockn == 1:
dy = 0
@@ -2613,6 +2626,11 @@ class TurtleArtWindow():
best_destination, selected_block, dy)
self._cascade_expandable(best_destination)
grow_stack_arm(find_sandwich_top(best_destination))
+ # If we are in an expandable flow, expand it...
+ blk, dockn = self._expandable_flow_above(selected_block)
+ while blk is not None:
+ self._resize_clamp(blk, blk.connections[dockn], dockn=dockn)
+ blk, dockn = self._expandable_flow_above(blk)
def _disconnect(self, blk):
''' Disconnect block from stack above it. '''
@@ -2628,6 +2646,7 @@ class TurtleArtWindow():
if blk in blk2.connections:
c = blk2.connections.index(blk)
blk2.connections[c] = None
+ blk3, dockn = self._expandable_flow_above(blk)
if blk2.name in block_styles['boolean-style']:
if c == 2 and blk2.ey > 0:
@@ -2641,9 +2660,62 @@ class TurtleArtWindow():
self._expand_expandable(blk2, blk, dy)
self._cascade_expandable(blk2)
grow_stack_arm(find_sandwich_top(blk2))
-
+ # Fix me
+ elif blk2.name in EXPANDABLE_FLOW:
+ self._resize_clamp(blk2, blk2.connections[c], dockn=c)
+ while blk3 is not None and blk3.connections[dockn] is not None:
+ self._resize_clamp(blk3, blk3.connections[dockn], dockn=dockn)
+ blk3, dockn = self._expandable_flow_above(blk3)
blk.connections[0] = None
+ def _resize_clamp(self, blk, gblk, dockn=-2):
+ ''' If the content of a clamp changes, resize it '''
+ if dockn < 0:
+ dockn = len(blk.docks) + dockn
+ y1 = blk.docks[-1][3]
+ if blk.name in block_styles['clamp-style-else'] and dockn == 3:
+ blk.reset_y2()
+ else:
+ blk.reset_y()
+ dy = 0
+ # Calculate height of drag group
+ while gblk is not None:
+ dy += int((gblk.docks[-1][3] - gblk.docks[0][3]) / gblk.scale)
+ gblk = gblk.connections[-1]
+ # Clamp has room for one "standard" block by default
+ if dy > 0:
+ dy -= 21 # Fixme: don't hardcode
+ if blk.name in block_styles['clamp-style-else'] and dockn == 3:
+ blk.expand_in_y2(dy)
+ else:
+ blk.expand_in_y(dy)
+ y2 = blk.docks[-1][3]
+ # Move group below clamp up or down
+ if blk.connections[-1] is not None:
+ drag_group = find_group(blk.connections[-1])
+ for gblk in drag_group:
+ gblk.spr.move_relative((0, y2-y1))
+ # We may have to move the else clamp group down too.
+ if blk.name in block_styles['clamp-style-else'] and dockn == 2:
+ if blk.connections[3] is not None:
+ drag_group = find_group(blk.connections[3])
+ for gblk in drag_group:
+ gblk.spr.move_relative((0, y2-y1))
+
+ def _expandable_flow_above(self, blk):
+ ''' Is there an expandable flow block above this one? '''
+ while blk.connections[0] is not None:
+ if blk.connections[0].name in EXPANDABLE_FLOW:
+ if blk.connections[0].name == 'ifelse':
+ if blk.connections[0].connections[-2] == blk:
+ return blk.connections[0], -2
+ return blk.connections[0], -3
+ else:
+ if blk.connections[0].connections[-2] == blk:
+ return blk.connections[0], -2
+ blk = blk.connections[0]
+ return None, None
+
def _import_from_journal(self, blk):
''' Import a file from the Sugar Journal '''
# TODO: check blk name to set filter
@@ -3211,8 +3283,6 @@ class TurtleArtWindow():
# Some blocks can only appear once...
if btype in ['start', 'hat1', 'hat2']:
if self._check_for_duplicate(btype):
- debug_output('WARNING: load block found duplicate %s' % (
- btype), True)
name = block_names[btype][0]
while self._find_proto_name('stack_%s' % (name), name):
name += '_2'
@@ -3231,9 +3301,7 @@ class TurtleArtWindow():
else:
i = b[4][1] - len(self._process_block_data)
name = self._extra_block_data[i][1][1]
- if self._find_proto_name('stack_%s' % (name), name):
- debug_output('WARNING: load block found duplicate %s: %s' % (
- btype, name), True)
+ while self._find_proto_name('stack_%s' % (name), name):
name += '_2'
if b[4][1] < len(self._process_block_data):
dblk = self._process_block_data[i]
@@ -3370,13 +3438,21 @@ class TurtleArtWindow():
blk.spr.set_label(' ')
blk.resize()
elif btype in EXPANDABLE or btype in expandable_blocks or \
- btype in EXPANDABLE_ARGS or btype == 'nop':
+ btype in EXPANDABLE_FLOW or btype in EXPANDABLE_ARGS or \
+ btype == 'nop':
if btype == 'vspace' or btype in expandable_blocks:
if value is not None:
blk.expand_in_y(value)
elif btype == 'hspace' or btype == 'identity2':
if value is not None:
blk.expand_in_x(value)
+ elif btype in EXPANDABLE_FLOW:
+ if value is not None:
+ if type(value) is int:
+ blk.expand_in_y(value)
+ else: # thenelse blocks
+ blk.expand_in_y(value[0])
+ blk.expand_in_y2(value[1])
elif btype == 'templatelist' or btype == 'list':
for i in range(len(b[4]) - 4):
blk.add_arg()
@@ -3440,51 +3516,53 @@ class TurtleArtWindow():
def assemble_data_to_save(self, save_turtle=True, save_project=True):
''' Pack the project (or stack) into a datastream to be serialized '''
- _data = []
- _blks = []
+ data = []
+ blks = []
if save_project:
- _blks = self.just_blocks()
+ blks = self.just_blocks()
else:
if self.selected_blk is None:
return []
- _blks = find_group(find_top_block(self.selected_blk))
-
- for _i, _blk in enumerate(_blks):
- _blk.id = _i
- for _blk in _blks:
- if _blk.name in content_blocks or _blk.name in COLLAPSIBLE:
- if len(_blk.values) > 0:
- _name = (_blk.name, _blk.values[0])
+ blks = find_group(find_top_block(self.selected_blk))
+
+ for i, blk in enumerate(blks):
+ blk.id = i
+ for blk in blks:
+ if blk.name in content_blocks or blk.name in COLLAPSIBLE:
+ if len(blk.values) > 0:
+ name = (blk.name, blk.values[0])
else:
- _name = (_blk.name)
- elif _blk.name in block_styles['basic-style-var-arg'] and \
- len(_blk.values) > 0:
- _name = (_blk.name, _blk.values[0])
- elif _blk.name in EXPANDABLE or _blk.name in expandable_blocks or\
- _blk.name in EXPANDABLE_ARGS:
- _ex, _ey = _blk.get_expand_x_y()
- if _ex > 0:
- _name = (_blk.name, _ex)
- elif _ey > 0:
- _name = (_blk.name, _ey)
+ name = (blk.name)
+ elif blk.name in block_styles['basic-style-var-arg'] and \
+ len(blk.values) > 0:
+ name = (blk.name, blk.values[0])
+ elif blk.name in EXPANDABLE or blk.name in expandable_blocks or \
+ blk.name in EXPANDABLE_ARGS or blk.name in EXPANDABLE_FLOW:
+ ex, ey, ey2 = blk.get_expand_x_y()
+ if blk.name in block_styles['clamp-style-else']:
+ name = (blk.name, (ey, ey2))
+ elif ex > 0:
+ name = (blk.name, ex)
+ elif ey > 0:
+ name = (blk.name, ey)
else:
- _name = (_blk.name, 0)
- elif _blk.name == 'start': # save block_size in start block
- _name = (_blk.name, self.block_scale)
+ name = (blk.name, 0)
+ elif blk.name == 'start': # save block_size in start block
+ name = (blk.name, self.block_scale)
else:
- _name = (_blk.name)
- if hasattr(_blk, 'connections') and _blk.connections is not None:
- connections = [get_id(_cblk) for _cblk in _blk.connections]
+ name = (blk.name)
+ if hasattr(blk, 'connections') and blk.connections is not None:
+ connections = [get_id(cblk) for cblk in blk.connections]
else:
connections = None
- (_sx, _sy) = _blk.spr.get_xy()
+ (sx, sy) = blk.spr.get_xy()
# Add a slight offset for copy/paste
if not save_project:
- _sx += 20
- _sy += 20
- _data.append((_blk.id, _name, _sx - self.canvas.cx,
- _sy - self.canvas.cy, connections))
+ sx += 20
+ sy += 20
+ data.append((blk.id, name, sx - self.canvas.cx,
+ sy - self.canvas.cy, connections))
if save_turtle:
for turtle in iter(self.turtles.dict):
# Don't save remote turtles
@@ -3492,11 +3570,11 @@ class TurtleArtWindow():
# Save default turtle as 'Yertle'
if turtle == self.nick:
turtle = DEFAULT_TURTLE
- _data.append((-1, ['turtle', turtle],
+ data.append((-1, ['turtle', turtle],
self.canvas.xcor, self.canvas.ycor,
self.canvas.heading, self.canvas.color,
self.canvas.shade, self.canvas.pensize))
- return _data
+ return data
def display_coordinates(self, clear=False):
''' Display the coordinates of the current turtle on the toolbar '''
@@ -3821,7 +3899,6 @@ class TurtleArtWindow():
except KeyError:
raise logoerror("#emptybox")
-
def dock_dx_dy(self, block1, dock1n, block2, dock2n):
''' Find the distance between the dock points of two blocks. '''
# Cannot dock a block to itself
@@ -3844,6 +3921,11 @@ class TurtleArtWindow():
dock1n == len(block1.connections) - 1 and \
block1.connections[dock1n] is not None:
self.inserting_block_mid_stack = True
+ elif block1.connections is not None and \
+ block1.name in EXPANDABLE_FLOW and \
+ dock1n == 2 and \
+ block1.connections[dock1n] is not None:
+ self.inserting_block_mid_stack = True
# Only number blocks can be docked when the dock is not empty
elif d2type is not 'number' or dock2n is not 0:
if block1.connections is not None and \
diff --git a/plugins/turtle_blocks_extras/turtle_blocks_extras.py b/plugins/turtle_blocks_extras/turtle_blocks_extras.py
index ade0508..7a9fc03 100644
--- a/plugins/turtle_blocks_extras/turtle_blocks_extras.py
+++ b/plugins/turtle_blocks_extras/turtle_blocks_extras.py
@@ -96,8 +96,10 @@ class Turtle_blocks_extras(Plugin):
# internally expanded macro
palette.add_block('while',
- style='flow-style-boolean',
- label=[_('while'), ' ', ' '],
+ # style='flow-style-boolean',
+ style='clamp-style-boolean',
+ # label=[_('while'), ' ', ' '],
+ label=_('while'),
prim_name='while',
default=[None, None, None],
special_name=_('while'),
@@ -106,8 +108,10 @@ boolean operators from Numbers palette'))
# internally expanded macro
palette.add_block('until',
- style='flow-style-boolean',
- label=[_('until'), ' ', ' '],
+ # style='flow-style-boolean',
+ style='clamp-style-boolean',
+ # label=[_('until'), ' ', ' '],
+ label=_('until'),
prim_name='until',
default=[None, None, None],
special_name=_('until'),