Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tablock.py33
-rw-r--r--taconstants.py258
-rw-r--r--talogo.py2
-rwxr-xr-xtasprite_factory.py103
-rw-r--r--tawindow.py127
5 files changed, 356 insertions, 167 deletions
diff --git a/tablock.py b/tablock.py
index 895d31b..5c9df4d 100644
--- a/tablock.py
+++ b/tablock.py
@@ -80,7 +80,7 @@ class Block:
# debug code
# etc.
def __init__(self, block_list, sprite_list, name, x, y, type='block',
- values=[], scale=BLOCK_SCALE, colors=["#00FF00","#00A000"]):
+ values=[], scale=BLOCK_SCALE, colors=["#0000FF","#0000A0"]):
self.spr = None
self.shapes = []
self.name = name
@@ -88,6 +88,7 @@ class Block:
self.scale = scale
self.docks = None
self.connections = None
+ self.status = None
self.values = []
self.primitive = None
self.type = type
@@ -127,9 +128,7 @@ class Block:
if self._dx != 0:
if self._dx < 0:
self._dx = 0
- self._make_block(self.svg)
- self._set_margins()
- self.spr.set_shape(self.shapes[0])
+ self.refresh()
# We may want to rescale blocks as well.
def rescale(self, scale):
@@ -146,10 +145,13 @@ class Block:
self._ey *= self.scale
self._set_label_attributes()
self.svg.set_scale(self.scale)
+ self.refresh()
+ self.spr.draw()
+
+ def refresh(self):
self._make_block(self.svg)
self._set_margins()
self.spr.set_shape(self.shapes[0])
- self.spr.draw()
# We may want to add additional slots for arguments ("innies").
def add_arg(self, keep_expanding=True):
@@ -159,9 +161,7 @@ class Block:
self.svg.set_show(True)
else:
self.svg.set_show(False)
- self._make_block(self.svg)
- self._set_margins()
- self.spr.set_shape(self.shapes[0])
+ self.refresh()
return self.svg.get_height()-h
# We may want to grow a block vertically.
@@ -173,9 +173,7 @@ class Block:
else:
self.svg.set_hide(False)
self.svg.set_show(False)
- self._make_block(self.svg)
- self._set_margins()
- self.spr.set_shape(self.shapes[0])
+ self.refresh()
# We may want to grow a block horizontally.
def expand_in_x(self, dx):
@@ -186,9 +184,7 @@ class Block:
else:
self.svg.set_hide(False)
self.svg.set_show(False)
- self._make_block(self.svg)
- self._set_margins()
- self.spr.set_shape(self.shapes[0])
+ self.refresh()
def reset_x(self):
dx = -self._ex
@@ -198,9 +194,7 @@ class Block:
self.svg.set_show(True)
else:
self.svg.set_show(False)
- self._make_block(self.svg)
- self._set_margins()
- self.spr.set_shape(self.shapes[0])
+ self.refresh()
return dx
def reset_y(self):
@@ -211,9 +205,7 @@ class Block:
self.svg.set_show(True)
else:
self.svg.set_show(False)
- self._make_block(self.svg)
- self._set_margins()
- self.spr.set_shape(self.shapes[0])
+ self.refresh()
return dy
def get_expand_x_y(self):
@@ -630,6 +622,7 @@ class Block:
['flow', False, self.svg.docks[4][0],
self.svg.docks[4][1], ']']]
+ # Depreciated block styles
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/taconstants.py b/taconstants.py
index 09baad6..a515e78 100644
--- a/taconstants.py
+++ b/taconstants.py
@@ -87,7 +87,7 @@ for Sugar toolbars.
from gettext import gettext as _
#
-# sprite layers
+# Sprite layers
#
HIDE_LAYER = 100
@@ -101,7 +101,7 @@ STATUS_LAYER = 900
TOP_LAYER = 1000
#
-# block palette categories
+# Block-palette categories
#
PALETTE_NAMES = ['turtle', 'pen', 'colors', 'numbers', 'flow', 'blocks',
@@ -124,14 +124,15 @@ PALETTES = [['forward', 'back', 'clean', 'left', 'right', 'show',
'storeinbox1', 'storeinbox2', 'string', 'box1', 'box2', 'box',
'storein', 'start'],
['kbinput', 'push', 'printheap', 'keyboard', 'pop', 'clearheap',
- 'myfunc', 'nop', 'addturtle', 'print', 'comment'],
- ['journal', 'audio', 'description', 'list',
+ 'myfunc', 'nop', 'sandwichtop', 'sandwichbottom',
+ 'addturtle', 'print', 'comment'],
+ ['journal', 'audio', 'description', 'picturelist',
'hideblocks', 'showblocks', 'fullscreen',
'picture1x1', 'picture2x2', 'picture2x1', 'picture1x2', 'savepix'],
['empty', 'restoreall']]
#
-# block style attributes
+# Block-style attributes
#
COLORS = [["#00FF00","#00A000"], ["#00FFFF","#00A0A0"], ["#00FFFF","#00A0A0"],
@@ -165,14 +166,15 @@ PALETTE_DEFAULT_SCALE = 1.5
PALETTE_SCALE = {'template2x2':1.0, 'template1x2':1.0}
#
-# block style definitions
+# Block-style definitions
#
BASIC_STYLE_HEAD = ['start', 'hat1', 'hat2', 'restore', 'restoreall']
BASIC_STYLE_HEAD_1ARG = ['hat']
BASIC_STYLE_TAIL = ['stopstack', 'empty']
BASIC_STYLE = ['clean', 'penup', 'pendown', 'stack1', 'stack2', 'vspace',
'hideblocks', 'showblocks', 'clearheap', 'printheap', 'kbinput',
- 'picture1x1', 'picture2x2', 'picture2x1', 'picture1x2', 'fullscreen']
+ 'picturelist', 'picture1x1', 'picture2x2', 'picture2x1', 'picture1x2',
+ 'fullscreen', 'sandwichtop', 'sandwichbottom']
BASIC_STYLE_1ARG = ['forward', 'back', 'left', 'right', 'seth', 'show',
'setscale', 'setpensize', 'setcolor', 'setshade', 'print', 'showaligned',
'settextsize', 'settextcolor', 'print', 'wait', 'storeinbox1', 'savepix',
@@ -197,12 +199,15 @@ FLOW_STYLE = ['forever', 'hspace']
FLOW_STYLE_1ARG = ['repeat']
FLOW_STYLE_BOOLEAN = ['if']
FLOW_STYLE_ELSE = ['ifelse']
+
+# Depreciated block styles
PORTFOLIO_STYLE_2x2 = ['template2x2']
BULLET_STYLE = ['templatelist', 'list']
PORTFOLIO_STYLE_1x1 = ['template1x1', 'template1x1a']
PORTFOLIO_STYLE_2x1 = ['template2x1']
PORTFOLIO_STYLE_1x2 = ['template1x2']
+
#
# Macros (groups of blocks)
#
@@ -218,122 +223,154 @@ MACROS = {
[8, 'vspace', 0, 0, [3, 9]],
[9, 'wait', 0, 0, [8, 10, None]],
[10, ['number', '1'], 0, 0, [9, None]]],
+ 'picturelist':
+ [[0, 'comment', 0, 0, [None, 1, 2]],
+ [1, ['string', _('bulleted list')], 0, 0, [0, None]],
+ [2, 'sandwichtop', 0, 0, [0, 3]],
+ [3, 'setxy', 0, 0, [2, 4, 5, 6]],
+ [4, 'titlex', 0, 0, [3, None]],
+ [5, 'titley', 0, 0, [3, None]],
+ [6, 'show', 0, 0, [3, 7, 8]],
+ [7, ['string',_('Title')], 0, 0, [6, None]],
+ [8, 'setxy', 0, 0, [6, 9, 10, 11]],
+ [9, 'leftx', 0, 0, [8, None]],
+ [10, 'topy', 0, 0, [8, None]],
+ [11, 'list', 0, 0, [8, 12, 13, 14]],
+ [12, ['string','∙ '], 0, 0, [11, None]],
+ [13, ['string','∙ '], 0, 0, [11, None]],
+ [14, 'sandwichbottom', 0, 0, [11, None]]],
'picture1x1':
- [[0, 'setxy', 0, 0, [None, 1, 2, 3]],
- [1, 'titlex', 0, 0, [0, None]],
- [2, 'titley', 0, 0, [0, None]],
- [3, 'show', 0, 0, [0, 4, 5]],
- [4, ['string',_('Title')], 0, 0, [3, None]],
- [5, 'setscale', 0, 0, [3, 6, 7]],
- [6, ['number', '90'], 0, 0, [5, None]],
- [7, 'setxy', 0, 0, [5, 8, 9, 10]],
- [8, 'leftx', 0, 0, [7, None]],
- [9, 'topy', 0, 0, [7, None]],
- [10, 'showaligned', 0, 0, [7, 11, None]],
- [11, 'journal', 0, 0, [10, None]]],
+ [[0, 'comment', 0, 0, [None, 1, 2]],
+ [1, ['string', _('picture')], 0, 0, [0, None]],
+ [2, 'sandwichtop', 0, 0, [0, 3]],
+ [3, 'setxy', 0, 0, [2, 4, 5, 6]],
+ [4, 'titlex', 0, 0, [3, None]],
+ [5, 'titley', 0, 0, [3, None]],
+ [6, 'show', 0, 0, [3, 7, 8]],
+ [7, ['string',_('Title')], 0, 0, [6, None]],
+ [8, 'setscale', 0, 0, [6, 9, 10]],
+ [9, ['number', '90'], 0, 0, [8, None]],
+ [10, 'setxy', 0, 0, [8, 11, 12, 13]],
+ [11, 'leftx', 0, 0, [10, None]],
+ [12, 'topy', 0, 0, [10, None]],
+ [13, 'showaligned', 0, 0, [10, 14, 15]],
+ [14, 'journal', 0, 0, [13, None]],
+ [15, 'sandwichbottom', 0, 0, [13, None]]],
'picture2x2':
- [[0, 'setxy', 0, 0, [None, 1, 2, 3]],
- [1, 'titlex', 0, 0, [0, None]],
- [2, 'titley', 0, 0, [0, None]],
- [3, 'show', 0, 0, [0, 4, 5]],
- [4, ['string',_('Title')], 0, 0, [3, None]],
- [5, 'setscale', 0, 0, [3, 6, 7]],
- [6, ['number', '45'], 0, 0, [5, None]],
- [7, 'setxy', 0, 0, [5, 8, 9, 10]],
- [8, 'leftx', 0, 0, [7, None]],
- [9, 'topy', 0, 0, [7, None]],
- [10, 'showaligned', 0, 0, [7, 11, 12]],
- [11, 'journal', 0, 0, [10, None]],
- [12, 'setxy', 0, 0, [10, 13, 14, 15]],
- [13, 'rightx', 0, 0, [12, None]],
- [14, 'topy', 0, 0, [12, None]],
- [15, 'showaligned', 0, 0, [12, 16, 17]],
- [16, 'journal', 0, 0, [15, None]],
- [17, 'setxy', 0, 0, [15, 18, 19, 20]],
- [18, 'leftx', 0, 0, [17, None]],
- [19, 'bottomy', 0, 0, [17, None]],
- [20, 'showaligned', 0, 0, [17, 21, 22]],
- [21, 'journal', 0, 0, [20, None]],
- [22, 'setxy', 0, 0, [20, 23, 24, 25]],
- [23, 'rightx', 0, 0, [22, None]],
- [24, 'bottomy', 0, 0, [22, None]],
- [25, 'showaligned', 0, 0, [22, 26, None]],
- [26, 'journal', 0, 0, [25, None]]],
+ [[0, 'comment', 0, 0, [None, 1, 2]],
+ [1, ['string', _('2×2 pictures')], 0, 0, [0, None]],
+ [2, 'sandwichtop', 0, 0, [0, 3]],
+ [3, 'setxy', 0, 0, [2, 4, 5, 6]],
+ [4, 'titlex', 0, 0, [3, None]],
+ [5, 'titley', 0, 0, [3, None]],
+ [6, 'show', 0, 0, [3, 7, 8]],
+ [7, ['string',_('Title')], 0, 0, [6, None]],
+ [8, 'setscale', 0, 0, [6, 9, 10]],
+ [9, ['number', '45'], 0, 0, [8, None]],
+ [10, 'setxy', 0, 0, [8, 11, 12, 13]],
+ [11, 'leftx', 0, 0, [10, None]],
+ [12, 'topy', 0, 0, [10, None]],
+ [13, 'showaligned', 0, 0, [10, 14, 15]],
+ [14, 'journal', 0, 0, [13, None]],
+ [15, 'setxy', 0, 0, [13, 16, 17, 18]],
+ [16, 'rightx', 0, 0, [15, None]],
+ [17, 'topy', 0, 0, [15, None]],
+ [18, 'showaligned', 0, 0, [15, 19, 20]],
+ [19, 'journal', 0, 0, [18, None]],
+ [20, 'setxy', 0, 0, [18, 21, 22, 23]],
+ [21, 'leftx', 0, 0, [20, None]],
+ [22, 'bottomy', 0, 0, [20, None]],
+ [23, 'showaligned', 0, 0, [20, 24, 25]],
+ [24, 'journal', 0, 0, [23, None]],
+ [25, 'setxy', 0, 0, [23, 26, 27, 28]],
+ [26, 'rightx', 0, 0, [25, None]],
+ [27, 'bottomy', 0, 0, [25, None]],
+ [28, 'showaligned', 0, 0, [25, 29, 30]],
+ [29, 'journal', 0, 0, [28, None]],
+ [30, 'sandwichbottom', 0, 0, [28, None]]],
'picture2x1':
- [[0, 'setxy', 0, 0, [None, 1, 2, 3]],
- [1, 'titlex', 0, 0, [0, None]],
- [2, 'titley', 0, 0, [0, None]],
- [3, 'show', 0, 0, [0, 4, 5]],
- [4, ['string',_('Title')], 0, 0, [3, None]],
- [5, 'setscale', 0, 0, [3, 6, 7]],
- [6, ['number', '45'], 0, 0, [5, None]],
- [7, 'setxy', 0, 0, [5, 8, 9, 10]],
- [8, 'leftx', 0, 0, [7, None]],
- [9, 'topy', 0, 0, [7, None]],
- [10, 'showaligned', 0, 0, [7, 11, 12]],
- [11, 'journal', 0, 0, [10, None]],
- [12, 'setxy', 0, 0, [10, 13, 14, 15]],
- [13, 'rightx', 0, 0, [12, None]],
- [14, 'topy', 0, 0, [12, None]],
- [15, 'showaligned', 0, 0, [12, 16, 17]],
- [16, 'journal', 0, 0, [15, None]],
- [17, 'setxy', 0, 0, [15, 18, 19, 20]],
- [18, 'leftx', 0, 0, [17, None]],
- [19, 'bottomy', 0, 0, [17, None]],
- [20, 'showaligned', 0, 0, [17, 21, 22]],
- [21, 'description', 0, 0, [20, None]],
- [22, 'setxy', 0, 0, [20, 23, 24, 25]],
- [23, 'rightx', 0, 0, [22, None]],
- [24, 'bottomy', 0, 0, [22, None]],
- [25, 'showaligned', 0, 0, [22, 26, None]],
- [26, 'description', 0, 0, [25, None]]],
+ [[0, 'comment', 0, 0, [None, 1, 2]],
+ [1, ['string', _('2×1 pictures')], 0, 0, [0, None]],
+ [2, 'sandwichtop', 0, 0, [0, 3]],
+ [3, 'setxy', 0, 0, [2, 4, 5, 6]],
+ [4, 'titlex', 0, 0, [3, None]],
+ [5, 'titley', 0, 0, [3, None]],
+ [6, 'show', 0, 0, [3, 7, 8]],
+ [7, ['string',_('Title')], 0, 0, [6, None]],
+ [8, 'setscale', 0, 0, [6, 9, 10]],
+ [9, ['number', '45'], 0, 0, [8, None]],
+ [10, 'setxy', 0, 0, [8, 11, 12, 13]],
+ [11, 'leftx', 0, 0, [10, None]],
+ [12, 'topy', 0, 0, [10, None]],
+ [13, 'showaligned', 0, 0, [10, 14, 15]],
+ [14, 'journal', 0, 0, [13, None]],
+ [15, 'setxy', 0, 0, [13, 16, 17, 18]],
+ [16, 'rightx', 0, 0, [15, None]],
+ [17, 'topy', 0, 0, [15, None]],
+ [18, 'showaligned', 0, 0, [15, 19, 20]],
+ [19, 'journal', 0, 0, [18, None]],
+ [20, 'setxy', 0, 0, [18, 21, 22, 23]],
+ [21, 'leftx', 0, 0, [20, None]],
+ [22, 'bottomy', 0, 0, [20, None]],
+ [23, 'showaligned', 0, 0, [20, 24, 25]],
+ [24, 'description', 0, 0, [23, None]],
+ [25, 'setxy', 0, 0, [23, 26, 27, 28]],
+ [26, 'rightx', 0, 0, [25, None]],
+ [27, 'bottomy', 0, 0, [25, None]],
+ [28, 'showaligned', 0, 0, [25, 29, 30]],
+ [29, 'description', 0, 0, [28, None]],
+ [30, 'sandwichbottom', 0, 0, [28, None]]],
'picture1x2':
- [[0, 'setxy', 0, 0, [None, 1, 2, 3]],
- [1, 'titlex', 0, 0, [0, None]],
- [2, 'titley', 0, 0, [0, None]],
- [3, 'show', 0, 0, [0, 4, 5]],
- [4, ['string',_('Title')], 0, 0, [3, None]],
- [5, 'setscale', 0, 0, [3, 6, 7]],
- [6, ['number', '45'], 0, 0, [5, None]],
- [7, 'setxy', 0, 0, [5, 8, 9, 10]],
- [8, 'leftx', 0, 0, [7, None]],
- [9, 'topy', 0, 0, [7, None]],
- [10, 'showaligned', 0, 0, [7, 11, 12]],
- [11, 'journal', 0, 0, [10, None]],
- [12, 'setxy', 0, 0, [10, 13, 14, 15]],
- [13, 'rightx', 0, 0, [12, None]],
- [14, 'topy', 0, 0, [12, None]],
- [15, 'showaligned', 0, 0, [12, 16, 17]],
- [16, 'description', 0, 0, [15, None]],
- [17, 'setxy', 0, 0, [15, 18, 19, 20]],
- [18, 'leftx', 0, 0, [17, None]],
- [19, 'bottomy', 0, 0, [17, None]],
- [20, 'showaligned', 0, 0, [17, 21, 22]],
- [21, 'journal', 0, 0, [20, None]],
- [22, 'setxy', 0, 0, [20, 23, 24, 25]],
- [23, 'rightx', 0, 0, [22, None]],
- [24, 'bottomy', 0, 0, [22, None]],
- [25, 'showaligned', 0, 0, [22, 26, None]],
- [26, 'description', 0, 0, [25, None]]]
+ [[0, 'comment', 0, 0, [None, 1, 2]],
+ [1, ['string', _('1×2 pictures')], 0, 0, [0, None]],
+ [2, 'sandwichtop', 0, 0, [0, 3]],
+ [3, 'setxy', 0, 0, [2, 4, 5, 6]],
+ [4, 'titlex', 0, 0, [3, None]],
+ [5, 'titley', 0, 0, [3, None]],
+ [6, 'show', 0, 0, [3, 7, 8]],
+ [7, ['string',_('Title')], 0, 0, [6, None]],
+ [8, 'setscale', 0, 0, [6, 9, 10]],
+ [9, ['number', '45'], 0, 0, [8, None]],
+ [10, 'setxy', 0, 0, [8, 11, 12, 13]],
+ [11, 'leftx', 0, 0, [10, None]],
+ [12, 'topy', 0, 0, [10, None]],
+ [13, 'showaligned', 0, 0, [10, 14, 15]],
+ [14, 'journal', 0, 0, [13, None]],
+ [15, 'setxy', 0, 0, [13, 16, 17, 18]],
+ [16, 'rightx', 0, 0, [15, None]],
+ [17, 'topy', 0, 0, [15, None]],
+ [18, 'showaligned', 0, 0, [15, 19, 20]],
+ [19, 'description', 0, 0, [18, None]],
+ [20, 'setxy', 0, 0, [18, 21, 22, 23]],
+ [21, 'leftx', 0, 0, [20, None]],
+ [22, 'bottomy', 0, 0, [20, None]],
+ [23, 'showaligned', 0, 0, [20, 24, 25]],
+ [24, 'journal', 0, 0, [23, None]],
+ [25, 'setxy', 0, 0, [23, 26, 27, 28]],
+ [26, 'rightx', 0, 0, [25, None]],
+ [27, 'bottomy', 0, 0, [25, None]],
+ [28, 'showaligned', 0, 0, [25, 29, 30]],
+ [29, 'description', 0, 0, [28, None]],
+ [30, 'sandwichbottom', 0, 0, [28, None]]]
}
#
-# blocks that are expandable
+# Blocks that are expandable
#
EXPANDABLE = ['vspace', 'hspace', 'templatelist', 'list', 'identity2', 'myfunc']
#
-# Old block styles that need dock adjustments
+# Depreciated block styles that need dock adjustments
#
OLD_DOCK = ['and', 'or', 'plus', 'minus', 'division', 'product', 'remainder']
#
-# blocks that contain media
+# Blocks that contain media
#
CONTENT_BLOCKS = ['number', 'string', 'description', 'audio', 'journal']
#
-# block name dictionary used for labels
+# Block-name dictionary used for labels
#
BLOCK_NAMES = {
'addturtle':[_('turtle')],
@@ -389,10 +426,11 @@ BLOCK_NAMES = {
'pendown':[_('pen down')],
'pensize':[_('pen size')],
'penup':[_('pen up')],
- 'picture1x1':[_('picture1x1')],
- 'picture2x2':[_('picture2x2')],
- 'picture2x1':[_('picture2x1')],
- 'picture1x2':[_('picture1x2')],
+ 'picturelist':[_('bulleted list')],
+ 'picture1x1':[_('1×1 picture')],
+ 'picture2x2':[_('2×2 pictures')],
+ 'picture2x1':[_('2×1 pictures')],
+ 'picture1x2':[_('1×2 pictures')],
'plus2':['+'],
'pop':[_('pop')],
'printheap':[_('show heap')],
@@ -411,6 +449,8 @@ BLOCK_NAMES = {
'rightx':[_('picture right')],
'savepix':[_('save picture')],
'scale':[_('scale')],
+ 'sandwichtop':[_('top of stack')],
+ 'sandwichbottom':[_('bottom of stack')],
'setcolor':[_('set color')],
'seth':[_('set heading')],
'setpensize':[_('set pen size')],
@@ -519,6 +559,8 @@ PRIMITIVES = {
'right':'right',
'rightpos':'rpos',
'rightx':'rightx',
+ 'sandwichtop':'nop',
+ 'sandwichbottom':'nop',
'savepix':'savepix',
'scale':'scale',
'setcolor':'setcolor',
diff --git a/talogo.py b/talogo.py
index 20856b5..eafce5f 100644
--- a/talogo.py
+++ b/talogo.py
@@ -880,7 +880,7 @@ class LogoCode:
return
def prim_print(self, n, flag):
- if flag and self.tw.hide:
+ if flag and (self.tw.hide or self.tw.step_time == 0):
return
if type(n) == str or type(n) == unicode:
if n[0:6] == 'media_':
diff --git a/tasprite_factory.py b/tasprite_factory.py
index 6abd943..ec6fc87 100755
--- a/tasprite_factory.py
+++ b/tasprite_factory.py
@@ -353,6 +353,46 @@ class SVG:
svg += self._footer()
return self._header() + svg
+ def sandwich_top(self):
+ x = self._stroke_width/2.0
+ y = self._stroke_width/2.0+self._radius
+ svg = self._new_path(x, y)
+ svg += self._corner(1, -1)
+ svg += self._rline_to(self._radius+self._stroke_width, 0)
+ svg += self._do_slot()
+ svg += self._corner(1, 1)
+ svg += self._rline_to(-self._radius,0)
+ svg += self._do_tab()
+ svg += self._inverse_corner(-1, 1, 90, 0, 0)
+ svg += self._rline_to(-self._radius, 0)
+ svg += self._close_path()
+ self._calculate_w_h()
+ svg += self._style()
+ svg += self._footer()
+ return self._header() + svg
+
+ def sandwich_bottom(self):
+ x = self._stroke_width/2.0
+ y = self._stroke_width/2.0
+ svg = self._new_path(x, y)
+ svg += self._rline_to(self._radius, 0)
+ svg += self._inverse_corner(1, 1, 90, 0, 0)
+ svg += self._do_slot()
+ svg += self._rline_to(self._radius, 0)
+ svg += self._corner(-1, 1)
+ svg += self._do_tab()
+ svg += self._rline_to(-self._radius-self._stroke_width,0)
+ svg += self._corner(-1, -1)
+ svg += self._close_path()
+ self._calculate_w_h()
+ svg += self._style()
+ if self._hide is True:
+ svg += self._hide_dot()
+ if self._show is True:
+ svg += self._show_dot()
+ svg += self._footer()
+ return self._header() + svg
+
#
# Utility methods
#
@@ -586,14 +626,30 @@ class SVG:
y = self._y + sign_y*self._radius
return self._arc_to(x, y, self._radius, a, l, s)
+ def _inverse_corner(self, sign_x, sign_y, a=90, l=0, s=1):
+ r2 = self._stroke_width+self._radius/2.0
+ if sign_x*sign_y == -1:
+ svg_str =self._rline_to(sign_x*(r2-self._stroke_width), 0)
+ else:
+ svg_str =self._rline_to(0, sign_y*+(r2-self._stroke_width))
+ x = self._x + sign_x*r2
+ y = self._y + sign_y*r2
+ svg_str += self._arc_to(x, y, r2, a, l, s)
+ # svg += self._rarc_to(sign_x, sign_y, 90, 0, 0)
+ if sign_x*sign_y == -1:
+ svg_str +=self._rline_to(0, sign_y*(r2-self._stroke_width))
+ else:
+ svg_str +=self._rline_to(sign_x*(r2-self._stroke_width), 0)
+ return svg_str
+
def _corner(self, sign_x, sign_y, a=90, l=0, s=1):
svg_str = ""
if sign_x == -1 and sign_y == 1:
- self._hide_x = self._x - self._radius/2 - self._stroke_width
- self._hide_y = self._y + self._radius/2 - self._stroke_width
+ self._hide_x = self._x - self._radius/2
+ self._hide_y = self._y + self._radius/2
if sign_x == -1 and sign_y == -1:
- self._show_x = self._x - self._radius/2 + self._stroke_width
- self._show_y = self._y - self._radius/2 - self._stroke_width
+ self._show_x = self._x - self._radius/2
+ self._show_y = self._y - self._radius/2
if self._radius > 0:
r2 = self._radius/2.0
if sign_x*sign_y == 1:
@@ -634,7 +690,7 @@ class SVG:
self._hide_y*scale)
self._fill, self._stroke = "#FFFFFF", "#FFFFFF"
svg += self._rect(10*scale2, 2*scale2, self._hide_x*scale-5*scale2,
- self._hide_y*scale-scale)
+ self._hide_y*scale-scale+scale2)
self._fill, self._stroke = _saved_fill, _saved_stroke
return svg
@@ -651,8 +707,8 @@ class SVG:
self._show_y*scale)
self._fill, self._stroke = "#FEFEFE", "#FEFEFE"
svg += self._rect(10*scale2, 2*scale2, self._show_x*scale-5*scale2,
- self._show_y*scale-scale)
- svg += self._rect(2*scale2, 10*scale2, self._show_x*scale-scale,
+ self._show_y*scale-scale+scale2)
+ svg += self._rect(2*scale2, 10*scale2, self._show_x*scale-scale+scale2,
self._show_y*scale-5*scale2)
self._fill, self._stroke = _saved_fill, _saved_stroke
return svg
@@ -829,31 +885,28 @@ def generator(datapath):
"""
svg0 = SVG()
- f = open_file(datapath, "portfolio-test.svg")
- svg0.set_scale(1)
- svg0.expand(25,15)
- svg0.set_slot(True)
- svg0.set_innie([True, True, False, True])
+ f = open_file(datapath, "sandwich_test2.svg")
+ svg0.set_scale(2)
svg0.set_tab(True)
- svg0.set_gradiant(True)
- svg0.set_draw_innies(False)
- svg_str = svg0.portfolio()
+ svg0.set_slot(True)
+ svg0.set_hide(True)
+ svg0.set_show(True)
+ svg_str = svg0.sandwich_bottom()
f.write(svg_str)
close_file(f)
- """
- svg1 = SVG()
- f = open_file(datapath, "blob-test.svg")
- svg1.set_scale(2)
- svg1.expand(0,20)
- svg1.set_tab(True)
- svg1.set_slot(True)
- svg1.set_gradiant(True)
- svg1.set_hide(True)
- svg_str = svg1.basic_block()
+ svg0 = SVG()
+ f = open_file(datapath, "sandwich_test.svg")
+ svg0.set_scale(2)
+ svg0.set_tab(True)
+ svg0.set_slot(True)
+ svg0.set_hide(True)
+ svg0.set_show(True)
+ svg_str = svg0.sandwich_top()
f.write(svg_str)
close_file(f)
+ """
svg2 = SVG()
f = open_file(datapath, "box-test.svg")
svg2.set_scale(1)
diff --git a/tawindow.py b/tawindow.py
index 0c522e4..712949c 100644
--- a/tawindow.py
+++ b/tawindow.py
@@ -294,7 +294,8 @@ class TurtleArtWindow():
self.hide = True
else:
for blk in self.just_blocks():
- blk.spr.set_layer(BLOCK_LAYER)
+ if blk.status != 'collapsed':
+ blk.spr.set_layer(BLOCK_LAYER)
self.show_palette()
self.hide = False
self.canvas.canvas.inval()
@@ -424,6 +425,7 @@ class TurtleArtWindow():
if self.palette_sprs[n][self.orientation] is not None:
self.palette_sprs[n][self.orientation].set_layer(CATEGORY_LAYER)
+ # TODO: use block margins to compute sizes dynamically
if self.palettes[n] == []:
for i, name in enumerate(PALETTES[n]):
# Some blocks are too big to fit the palette.
@@ -455,7 +457,8 @@ class TurtleArtWindow():
if n == PALETTE_NAMES.index('trash'):
for blk in self.trash_stack:
for b in self._find_group(blk):
- b.spr.set_layer(TAB_LAYER)
+ if b.status != 'collapsed':
+ b.spr.set_layer(TAB_LAYER)
"""
Hide the toolbar palettes
@@ -618,7 +621,7 @@ class TurtleArtWindow():
elif blk.name == 'empty':
self._empty_trash()
elif MACROS.has_key(blk.name):
- self._new_macro(blk.name, x, y)
+ self._new_macro(blk.name, x+100, y+100)
else:
blk.highlight()
self._new_block(blk.name, x, y)
@@ -685,15 +688,20 @@ class TurtleArtWindow():
self._restore_from_trash(self.trash_stack[len(self.trash_stack)-1])
def _restore_from_trash(self, blk):
+ # TODO: Collapsed stacks will have been restored before moving to trash.
group = self._find_group(blk)
for b in group:
b.rescale(self.block_scale)
- b.spr.set_layer(BLOCK_LAYER)
+ if blk.status != 'collapsed':
+ b.spr.set_layer(BLOCK_LAYER)
x,y = b.spr.get_xy()
b.spr.move((x+PALETTE_WIDTH,y+PALETTE_HEIGHT))
b.type = 'block'
for b in group:
self._adjust_dock_positions(b)
+ if b.name == 'sandwichbottom' and\
+ len(b.values) == 1 and b.values[0] != 0:
+ b.spr.move_relative((0, b.values[0]))
self.trash_stack.remove(blk)
"""
@@ -726,7 +734,8 @@ class TurtleArtWindow():
(sx, sy) = blk.spr.get_xy()
self.drag_pos = x-sx, y-sy
for blk in self.drag_group:
- blk.spr.set_layer(TOP_LAYER)
+ if blk.status != 'collapsed':
+ blk.spr.set_layer(TOP_LAYER)
self.saved_string = blk.spr.labels[0]
"""
@@ -752,6 +761,7 @@ class TurtleArtWindow():
newblk = Block(self.block_list, self.sprite_list, name, x-20, y-20,
'block', [], self.block_scale)
# Add special skin to some blocks
+ # TODO: use block margins to compute sizes dynamically
if name == 'nop':
if self.nop == 'pythonloaded':
newblk.spr.set_image(self.media_shapes['pythonon'], 1,
@@ -813,7 +823,9 @@ class TurtleArtWindow():
macro = MACROS[name]
macro[0][2] = x
macro[0][3] = y
- self.process_data(macro)
+ top = self.process_data(macro)
+ self.block_operation = 'new'
+ self.drag_group = self._find_group(top)
"""
Process data (from a macro, a file, or the clipboard) into blocks.
@@ -879,6 +891,7 @@ class TurtleArtWindow():
# Block sizes and shapes may have changed.
for b in blocks:
self._adjust_dock_positions(b)
+ return blocks[0]
"""
Adjust the dock x,y positions
@@ -943,6 +956,11 @@ class TurtleArtWindow():
# If we have a stack of blocks selected, move them.
elif self.drag_group[0] is not None:
blk = self.drag_group[0]
+ # Don't move a sandwichbottom is the stack is collapsed
+ if blk.name == 'sandwichbottom' and\
+ len(blk.values) == 1 and blk.values[0] != 0:
+ return
+
self.selected_spr = blk.spr
dragx, dragy = self.drag_pos
if mdx != 0 or mdy != 0:
@@ -1066,13 +1084,17 @@ class TurtleArtWindow():
blk = self.drag_group[0]
# Remove blocks by dragging them onto the trash palette
+ # TODO: Restore collapsed stacks before moving to trash.
if self.block_operation=='move' and self._in_the_trash(x, y):
self.trash_stack.append(blk)
for b in self.drag_group:
+ if b.type == 'collapsed':
+ self._restore_stack(self._find_top_of_sandwich(b))
+ """
b.type = 'trash'
b.rescale(self.trash_scale)
- # b.spr.hide()
blk.spr.move((x,y))
+ """
for b in self.drag_group:
self._adjust_dock_positions(b)
self.drag_group = None
@@ -1083,12 +1105,22 @@ class TurtleArtWindow():
if self.block_operation=='new':
for b in self.drag_group:
(bx, by) = b.spr.get_xy()
- b.spr.move((bx+200, by+120))
+ b.spr.move((bx+100, by+100))
# Look to see if we can dock the current stack.
self._snap_to_dock()
+ # When a sandwich bottom is docked, mark it as collapsable
+ if blk.name == 'sandwichbottom':
+ if len(blk.values) == 1 and blk.values[0] != 0:
+ blk.svg.set_show(True)
+ blk.svg.set_hide(False)
+ else:
+ blk.svg.set_hide(True)
+ blk.svg.set_show(False)
+ blk.refresh()
for b in self.drag_group:
- b.spr.set_layer(BLOCK_LAYER)
+ if b.status != 'collapsed':
+ b.spr.set_layer(BLOCK_LAYER)
self.drag_group = None
# Find the block we clicked on and process it.
@@ -1102,6 +1134,7 @@ class TurtleArtWindow():
blk = self.block_list.spr_to_block(self.selected_spr)
if blk is None:
return
+ print blk.name
self.selected_blk = blk
if blk.name=='number' or blk.name=='string':
self.saved_string = blk.spr.labels[0]
@@ -1157,11 +1190,72 @@ class TurtleArtWindow():
blk.connections[n-1] = argblk
else:
self._run_stack(blk)
+ elif blk.name=='sandwichbottom':
+ print "clicked on sandwich bottom"
+ if self._hide_button_hit(blk.spr, x, y):
+ top = self._find_sandwich_top(blk)
+ if top is not None:
+ print "collapsing stack"
+ blk.svg.set_show(True)
+ blk.svg.set_hide(False)
+ blk.refresh()
+ self._collapse_stack(top)
+ elif self._show_button_hit(blk.spr, x, y):
+ top = self._find_sandwich_top(blk)
+ if top is not None:
+ print "restoring stack"
+ blk.svg.set_show(False)
+ blk.svg.set_hide(True)
+ blk.refresh()
+ self._restore_stack(top)
elif blk.name=='nop' and self.myblock==None:
self._import_py()
else:
self._run_stack(blk)
+ def _find_sandwich_top(self, blk):
+ # TODO: Add nesting; detect branches (e.g., if, ifelse, repeat)
+ b = blk.connections[0]
+ while b is not None:
+ if b.name == 'sandwichtop':
+ return b
+ b = b.connections[0]
+ return None
+
+ def _collapse_stack(self, top):
+ group = self._find_group(top.connections[len(top.connections)-1])
+ if group[0].name == 'sandwichbottom':
+ return
+ (x, y) = group[0].spr.get_xy()
+ dy = 0
+ for b in group:
+ if b.name == 'sandwichbottom':
+ (bx, by) = b.spr.get_xy()
+ dy = y-by
+ if len(b.values) == 0:
+ b.values.append(dy)
+ else:
+ b.values[0] = dy
+ if dy == 0:
+ b.spr.set_layer(HIDE_LAYER)
+ b.status = 'collapsed'
+ else:
+ b.spr.move_relative((0,dy))
+
+ def _restore_stack(self, top):
+ group = self._find_group(top.connections[len(top.connections)-1])
+ dy = 0
+ for b in group:
+ if b.name == 'sandwichbottom':
+ dy = b.values[0]
+ b.values[0] = 0
+ if dy == 0:
+ b.spr.set_layer(BLOCK_LAYER)
+ b.status = None
+ else:
+ print "restoring %s" % (b.name)
+ b.spr.move_relative((0,-dy))
+
"""
Run a stack of blocks.
"""
@@ -1330,6 +1424,9 @@ class TurtleArtWindow():
def _disconnect(self, blk):
if blk.connections[0]==None:
return
+ if blk.name == 'sandwichbottom' and\
+ len(blk.values) == 1 and blk.values[0] != 0:
+ return
blk2=blk.connections[0]
blk2.connections[blk2.connections.index(blk)] = None
blk.connections[0] = None
@@ -1588,7 +1685,9 @@ class TurtleArtWindow():
Jog block
"""
def _jog_block(self, blk, dx, dy):
- # drag entire stack if moving lock block
+ if blk.name == 'sandwichbottom' and\
+ len(blk.values) == 1 and blk.values[0] != 0:
+ return
self.drag_group = self._find_group(blk)
# check to see if any block ends up with a negative x
for blk in self.drag_group:
@@ -1675,7 +1774,7 @@ class TurtleArtWindow():
def load_files(self, ta_file, create_new_project=True):
if create_new_project is True:
self.new_project()
- self.process_data(data_from_file(ta_file))
+ top = self.process_data(data_from_file(ta_file))
def load_file(self, create_new_project=True):
fname, self.load_save_folder = get_load_name('.ta',
@@ -1717,6 +1816,7 @@ class TurtleArtWindow():
self.canvas.setshade(shade)
self.canvas.setpensize(pensize)
+ # TODO: handle collapsed blocks
"""
Restore individual blocks from saved state
"""
@@ -1818,7 +1918,7 @@ class TurtleArtWindow():
Start a new project with a 'start' brick
"""
def load_start(self):
- self.process_data([[0, "start", 218, 224, [None, None]]])
+ top = self.process_data([[0, "start", 218, 224, [None, None]]])
"""
Start a project to a file
@@ -1836,7 +1936,8 @@ class TurtleArtWindow():
data = self.assemble_data_to_save()
data_to_file(data, fname+'.ta')
self.save_file_name = os.path.basename(fname)
-
+
+ # TODO: handle collapsed blocks
"""
Pack the project (or stack) into a data stream to be serialized
"""