diff options
Diffstat (limited to 'TurtleArt')
-rw-r--r-- | TurtleArt/taconstants.py | 10 | ||||
-rw-r--r-- | TurtleArt/talogo.py | 15 | ||||
-rw-r--r-- | TurtleArt/taturtle.py | 28 | ||||
-rw-r--r-- | TurtleArt/tawindow.py | 112 |
4 files changed, 102 insertions, 63 deletions
diff --git a/TurtleArt/taconstants.py b/TurtleArt/taconstants.py index 1997d1b..e51c4d0 100644 --- a/TurtleArt/taconstants.py +++ b/TurtleArt/taconstants.py @@ -135,7 +135,7 @@ PALETTES = [['clean', 'forward', 'back', 'show', 'left', 'right', ['kbinput', 'push', 'printheap', 'keyboard', 'pop', 'clearheap', 'myfunc1arg', 'userdefined', 'addturtle', 'comment', 'print', 'cartesian', 'width', 'height', 'polar', 'sandwichtop_no_label', - 'sandwichbottom', 'readpixel', 'see'], + 'sandwichbottom', 'readpixel', 'see', 'skin'], ['journal', 'audio', 'description', 'hideblocks', 'showblocks', 'fullscreen', 'savepix', 'savesvg', 'picturelist', 'picture1x1a', 'picture1x1', 'picture2x2', 'picture2x1', @@ -196,7 +196,7 @@ BASIC_STYLE_1ARG = ['forward', 'back', 'left', 'right', 'seth', 'show', 'image', 'setscale', 'setpensize', 'setcolor', 'setshade', 'print', 'showaligned', 'settextsize', 'settextcolor', 'print', 'wait', 'storeinbox1', 'savepix', 'storeinbox2', 'wait', 'stack', 'push', 'nop', 'addturtle', 'comment', - 'savesvg', 'setgray'] + 'savesvg', 'setgray', 'skin'] BASIC_STYLE_VAR_ARG = ['userdefined', 'userdefined2args', 'userdefined3args'] BULLET_STYLE = ['templatelist', 'list'] BASIC_STYLE_2ARG = ['arc', 'setxy', 'fillscreen', 'storein', 'write'] @@ -383,6 +383,7 @@ BLOCK_NAMES = { 'show':[_('show')], 'showblocks':[_('show blocks')], 'showaligned':[_('show aligned')], + 'skin':[_('turtle shell')], 'sqrt':['√'], 'stack':[_('action')], 'stack1':[_('action 1')], @@ -526,6 +527,7 @@ PRIMITIVES = { 'show':'show', 'showblocks':'showblocks', 'showaligned':'showaligned', + 'skin':'skin', 'sqrt':'sqrt', 'stack':'stack', 'stack1':'stack1', @@ -609,6 +611,7 @@ DEFAULTS = { 'setxy':[0, 0], 'show':[_('text')], 'showaligned':[_('text')], + 'skin':[None], 'stack':[_('action')], 'storeinbox1':[100], 'storeinbox2':[100], @@ -638,7 +641,7 @@ STRING_OR_NUMBER_ARGS = ['plus2', 'equal2', 'less2', 'greater2', 'box', 'userdefined2args', 'userdefined3args', 'storein'] CONTENT_ARGS = ['show', 'showaligned', 'push', 'storein', 'storeinbox1', - 'storeinbox2'] + 'storeinbox2', 'skin'] # # Status blocks @@ -838,6 +841,7 @@ HELP_STRINGS = { 'shade':_("holds current pen shade"), 'show':_("draws text or show media from the Journal"), 'showblocks':_("restores hidden blocks"), + 'skin':_("put a shell on the turtle"), 'sqrt':_("calculates square root"), 'stack1':_("invokes Action 1 stack"), 'stack2':_("invokes Action 2 stack"), diff --git a/TurtleArt/talogo.py b/TurtleArt/talogo.py index d485d22..a9b13dc 100644 --- a/TurtleArt/talogo.py +++ b/TurtleArt/talogo.py @@ -348,6 +348,7 @@ class LogoCode: 'show':[1, lambda self, x: self.show(x, True)], 'showaligned':[1,lambda self, x: self.show(x, False)], 'showblocks':[0, lambda self: self.tw.showblocks()], + 'skin':[1, lambda self, x: self.reskin(x)], 'sound':[1, lambda self, x: self.play_sound(x)], 'sqrt':[1, lambda self, x: tasqrt(x)], 'stack1':[0, self.prim_stack1, True], @@ -1071,6 +1072,14 @@ class LogoCode: """ Set scale used by media object display """ self.scale = x + def reskin(self, media): + """ Reskin the turtle with an image from a file """ + w = int(self.scale) + h = int(self.scale) + pixbuf = self.show_picture(media, 0, 0, w, h, False) + if pixbuf is not None: + self.tw.active_turtle.set_shapes([pixbuf]) + def show(self, string, center=False): """ Show is the general-purpose media-rendering block. """ # convert from Turtle coordinates to screen coordinates @@ -1138,7 +1147,7 @@ class LogoCode: else: play_audio(self, audio[6:]) - def show_picture(self, media, x, y, w, h): + def show_picture(self, media, x, y, w, h, show=True): """ Image file from Journal """ if media == "" or media[6:] == "": pass @@ -1179,10 +1188,12 @@ class LogoCode: self.filepath = None self.tw.showlabel('nofile', media[6:]) print "Couldn't open media object %s" % (media[6:]) - if pixbuf is not None: + if pixbuf is not None and show: self.tw.canvas.draw_pixbuf(pixbuf, 0, 0, int(x), int(y), int(w), int(h), self.filepath) + else: + return pixbuf def show_description(self, media, x, y, w, h): """ Description field from Journal """ diff --git a/TurtleArt/taturtle.py b/TurtleArt/taturtle.py index 5272cd6..91e7dfc 100644 --- a/TurtleArt/taturtle.py +++ b/TurtleArt/taturtle.py @@ -24,12 +24,19 @@ from tasprite_factory import SVG, svg_str_to_pixbuf from tacanvas import wrap100, color_table from sprites import Sprite +import logging +_logger = logging.getLogger('turtleart-activity') + + +SHAPES = 36 + + def generate_turtle_pixbufs(colors): """ Generate pixbufs for generic turtles """ shapes = [] svg = SVG() svg.set_scale(1.0) - for i in range(36): + for i in range(SHAPES): svg.set_orientation(i*10) shapes.append(svg_str_to_pixbuf(svg.turtle(colors))) return shapes @@ -143,10 +150,25 @@ class Turtle: self.spr = None turtles.add_to_dict(key, self) + def set_shapes(self, shapes): + """ Reskin the turtle """ + n = len(shapes) + if n == SHAPES: + self.shapes = shapes[:] + else: + if n != 1: + _logger.debug("%d images passed to set_shapes: ignoring" % (n)) + images = [shapes[0]] + for i in range(3): + images.append(images[i].rotate_simple(90)) + for i in range(SHAPES): + j = (i + 4) % SHAPES + self.shapes[j] = images[int(j/9) % 4] + def set_heading(self, heading): - """ Set the turtle heading (and shape: one per 10 degrees) """ + """ Set the turtle heading (one shape per 360/SHAPES degrees) """ self.heading = heading - i = (int(self.heading+5)%360)/10 + i = (int(self.heading+5)%360)/(360 / SHAPES) if not self.hidden and self.spr is not None: try: self.spr.set_shape(self.shapes[i]) diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py index c97785a..aee66cf 100644 --- a/TurtleArt/tawindow.py +++ b/TurtleArt/tawindow.py @@ -1417,6 +1417,11 @@ class TurtleArtWindow(): gblk.spr.move_relative((0, dy * blk.scale)) grow_stack_arm(find_sandwich_top(blk)) elif blk.name in EXPANDABLE_BLOCKS: + # Connection may be lost during expansion, so store it... + blk0 = blk.connections[0] + if blk0 is not None: + dock0 = blk0.connections.index(blk) + if hide_button_hit(blk.spr, x, y): dy = blk.reset_y() elif show_button_hit(blk.spr, x, y): @@ -1427,7 +1432,12 @@ class TurtleArtWindow(): return self._expand_expandable(blk, blk.connections[1], dy) - self._cascade_expandable(blk, flag=True) + # and restore it... + if blk0 is not None: + blk.connections[0] = blk0 + blk0.connections[dock0] = blk + self._cascade_expandable(blk) + grow_stack_arm(find_sandwich_top(blk)) elif blk.name in EXPANDABLE_ARGS or blk.name == 'nop': @@ -1505,22 +1515,15 @@ class TurtleArtWindow(): for gblk in find_group(blk): gblk.spr.move_relative((0, -dy * blk.scale)) - def _cascade_expandable(self, blk, flag=False): + def _cascade_expandable(self, blk): """ If expanding/shrinking a block, cascade. """ - if flag: - print "cascading", blk.name while blk.name in NUMBER_STYLE or \ blk.name in NUMBER_STYLE_PORCH or \ - blk.name in NUMBER_STYLE_BLOCK or \ - (flag and blk.name in COMPARE_STYLE): + blk.name in NUMBER_STYLE_BLOCK: if blk.connections[0] is None: - if flag: - print "connections[0] is None" break if blk.connections[0].name in EXPANDABLE_BLOCKS: blk = blk.connections[0] - if flag: - print "expanding", blk.name dy = 20 + blk.connections[1].ey - blk.ey blk.expand_in_y(dy) if dy != 0: @@ -1529,13 +1532,9 @@ class TurtleArtWindow(): for gblk in find_group(blk): if gblk not in group: gblk.spr.move_relative((0, dy * blk.scale)) - if flag: - print "moving", gblk.name, dy if blk.name in COMPARE_STYLE: for gblk in find_group(blk): gblk.spr.move_relative((0, -dy * blk.scale)) - if flag: - print "moving", gblk.name, -dy def _check_collapsibles(self, blk): """ Check the state of collapsible blocks upon change in dock state. """ @@ -1576,12 +1575,13 @@ class TurtleArtWindow(): pass def _snap_to_dock(self): - """ Snap a block (dragged_block) to the dock of another block + """ Snap a block (selected_block) to the dock of another block (destination_block). """ - dragged_block = self.drag_group[0] + selected_block = self.drag_group[0] + best_destination = None d = 200 - for dragged_block_dockn in range(len(dragged_block.docks)): + for selected_block_dockn in range(len(selected_block.docks)): for destination_block in self.just_blocks(): # Don't link to a block to which you're already connected if destination_block in self.drag_group: @@ -1589,17 +1589,17 @@ class TurtleArtWindow(): # Check each dock of destination for a possible connection for destination_dockn in range(len(destination_block.docks)): this_xy = dock_dx_dy(destination_block, destination_dockn, - dragged_block, dragged_block_dockn) + selected_block, selected_block_dockn) if magnitude(this_xy) > d: continue d = magnitude(this_xy) best_xy = this_xy best_destination = destination_block best_destination_dockn = destination_dockn - best_dragged_block_dockn = dragged_block_dockn + best_selected_block_dockn = selected_block_dockn if d < 200: - if not arithmetic_check(dragged_block, best_destination, - best_dragged_block_dockn, + if not arithmetic_check(selected_block, best_destination, + best_selected_block_dockn, best_destination_dockn): return for blk in self.drag_group: @@ -1612,31 +1612,58 @@ class TurtleArtWindow(): blk_in_dock.connections[0] = None self._put_in_trash(blk_in_dock) - best_destination.connections[best_destination_dockn] = dragged_block - if dragged_block.connections is not None: - dragged_block.connections[best_dragged_block_dockn] = \ + best_destination.connections[best_destination_dockn] = \ + selected_block + if selected_block.connections is not None: + selected_block.connections[best_selected_block_dockn] = \ best_destination if best_destination.name in BOOLEAN_STYLE: if best_destination_dockn == 2 and \ - dragged_block.name in COMPARE_STYLE: - dy = dragged_block.ey - best_destination.ey + selected_block.name in COMPARE_STYLE: + dy = selected_block.ey - best_destination.ey best_destination.expand_in_y(dy) - self._expand_boolean(best_destination, dragged_block, dy) + self._expand_boolean(best_destination, selected_block, dy) elif best_destination.name in EXPANDABLE_BLOCKS and \ best_destination_dockn == 1: dy = 0 - if dragged_block.name in EXPANDABLE_BLOCKS: - dy = 20 + dragged_block.ey - best_destination.ey + if selected_block.name in EXPANDABLE_BLOCKS: + dy = 20 + selected_block.ey - best_destination.ey best_destination.expand_in_y(dy) else: if best_destination.ey > 0: dy = best_destination.reset_y() if dy != 0: - self._expand_expandable(best_destination, dragged_block, dy) + self._expand_expandable(best_destination, selected_block, + dy) self._cascade_expandable(best_destination) grow_stack_arm(find_sandwich_top(best_destination)) + def _disconnect(self, blk): + """ Disconnect block from stack above it. """ + if blk.connections[0] == None: + return + if collapsed(blk): + return + blk2 = blk.connections[0] + c = blk2.connections.index(blk) + blk2.connections[c] = None + + if blk2.name in BOOLEAN_STYLE: + if c == 2 and blk2.ey > 0: + dy = -blk2.ey + blk2.expand_in_y(dy) + self._expand_boolean(blk2, blk, dy) + elif blk2.name in EXPANDABLE_BLOCKS and c == 1: + if blk2.ey > 0: + dy = blk2.reset_y() + if dy != 0: + self._expand_expandable(blk2, blk, dy) + self._cascade_expandable(blk2) + grow_stack_arm(find_sandwich_top(blk2)) + + blk.connections[0] = None + def _import_from_journal(self, blk): """ Import a file from the Sugar Journal """ if self.running_sugar: @@ -1709,31 +1736,6 @@ class TurtleArtWindow(): blk.set_image(pixbuf, x, y) self._resize_skin(blk) - def _disconnect(self, blk): - """ Disconnect block from stack above it. """ - if blk.connections[0] == None: - return - if collapsed(blk): - return - blk2 = blk.connections[0] - c = blk2.connections.index(blk) - blk2.connections[c] = None - - if blk2.name in BOOLEAN_STYLE: - if c == 2 and blk2.ey > 0: - dy = -blk2.ey - blk2.expand_in_y(dy) - self._expand_boolean(blk2, blk, dy) - elif blk2.name in EXPANDABLE_BLOCKS and c == 1: - if blk2.ey > 0: - dy = blk2.reset_y() - if dy != 0: - self._expand_expandable(blk2, blk, dy) - self._cascade_expandable(blk2) - grow_stack_arm(find_sandwich_top(blk2)) - - blk.connections[0] = None - def _keypress_cb(self, area, event): """ Keyboard """ keyname = gtk.gdk.keyval_name(event.keyval) |