From b6ef5e8be4b29619dccb016d3f85215be95c8998 Mon Sep 17 00:00:00 2001 From: Walter Bender Date: Wed, 10 Feb 2010 03:41:46 +0000 Subject: more collapsible block updates --- 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 """ -- cgit v0.9.1