diff options
author | Walter Bender <walter@walter-laptop.(none)> | 2010-02-03 15:54:47 (GMT) |
---|---|---|
committer | Walter Bender <walter@walter-laptop.(none)> | 2010-02-03 15:54:47 (GMT) |
commit | 2573df3606380970efb3a106bff10dba0437b6be (patch) | |
tree | aea4a88d7ba34af4a6d6278617b48909835cc809 | |
parent | 7ae60da4a97263c7f2d95cdc934f1e3c0a62f45d (diff) |
fixed boolean problem
-rw-r--r-- | block.py | 5 | ||||
-rw-r--r-- | talogo.py | 429 | ||||
-rw-r--r-- | tautils.py | 35 | ||||
-rw-r--r-- | tawindow.py | 131 |
4 files changed, 327 insertions, 273 deletions
@@ -83,7 +83,6 @@ class Block: self.docks = None self.connections = None self.values = [] - self.content = None self.primitive = None self.type = type self._dx = 0 @@ -105,10 +104,6 @@ class Block: self._new_block_from_factory(sprite_list, x, y) - # TODO: add media block graphics here - if name in CONTENT_BLOCKS: - self.content = self.name - if PRIMITIVES.has_key(name): self.primitive = PRIMITIVES[self.name] @@ -38,7 +38,8 @@ except: from constants import * from tagplay import play_audio, play_movie_from_file, stop_media from tajail import myfunc, myfunc_import - +from tautils import get_pixbuf_from_journal, movie_media_type,\ + audio_media_type, round_int from gettext import gettext as _ procstop = False @@ -63,18 +64,9 @@ class logoerror(Exception): def __str__(self): return repr(self.value) -# -# Utility functions -# -def movie_media_type(suffix): - if suffix.replace('.','') in ['ogv','vob','mp4','wmv','mov', 'mpeg']: - return True - return False - -def audio_media_type(suffix): - if suffix.replace('.','') in ['ogg', 'oga', 'm4a']: - return True - return False +""" +Utility functions +""" def careful_divide(x,y): try: @@ -153,45 +145,6 @@ def start_stack(tw): if tw.running_sugar: tw.activity.recenter() -def display_coordinates(tw, a=-1, b=-1, d=-1): - if a==-1 and b==-1 and d == -1: - x = round_int(tw.canvas.xcor/tw.coord_scale) - y = round_int(tw.canvas.ycor/tw.coord_scale) - h = round_int(tw.canvas.heading) - else: - x = a - y = b - h = d - if tw.running_sugar: - tw.activity.coordinates_label.set_text("%s: %d %s: %d %s: %d" % ( - _("xcor"), x, _("ycor"), y, _("heading"), h)) - tw.activity.coordinates_label.show() - -def round_int(n): - if int(float(n)) == n: - return int(n) - else: - nn = int(float(n+0.05)*10)/10. - if int(float(nn)) == nn: - return int(nn) - return nn - -def get_pixbuf_from_journal(dsobject, w, h): - try: - pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(dsobject.file_path, - int(w),int(h)) - except: - try: - pixbufloader = \ - gtk.gdk.pixbuf_loader_new_with_mime_type('image/png') - pixbufloader.set_size(min(300,int(w)),min(225,int(h))) - pixbufloader.write(dsobject.metadata['preview']) - pixbufloader.close() - pixbuf = pixbufloader.get_pixbuf() - except: - pixbuf = None - return pixbuf - def calc_position(tw, t): w,h,x,y,dx,dy = TEMPLATES[t] x *= tw.canvas.width @@ -212,9 +165,9 @@ def just_stop(): def millis(): return int(clock()*1000) -# -# A class for parsing Logo Code -# +""" +A class for parsing Logo Code +""" class LogoCode: def __init__(self, tw): @@ -228,7 +181,7 @@ class LogoCode: '*':[None, lambda self,x,y: x*y], '%':[None, lambda self,x,y: x%y], '+':[None, lambda self,x,y: x+y], - 'and':[None, lambda self,x,y: x&y], + 'and':[2, lambda self,x,y: x&y], 'arc':[2, lambda self, x, y: self.tw.canvas.arc(x, y)], 'back':[1, lambda self,x: self.tw.canvas.forward(-x)], 'blue':[0, lambda self: 70], @@ -252,7 +205,7 @@ class LogoCode: 'green':[0, lambda self: 30], 'heading':[0, lambda self: self.tw.canvas.heading], 'heap':[0, lambda self: self.heap_print()], - 'hideblocks':[0, lambda self: self.hideblocks()], + 'hideblocks':[0, lambda self: self.tw.hideblocks()], 'hres':[0, lambda self: self.tw.canvas.width/self.tw.coord_scale], 'id':[1, lambda self,x: identity(x)], 'if':[2, self.prim_if, True], @@ -272,7 +225,7 @@ class LogoCode: 'nop3':[1, lambda self,x: None], 'not':[1, lambda self,x:not x], 'orange':[0, lambda self: 10], - 'or':[None, lambda self,x,y: x|y], + 'or':[2, lambda self,x,y: x|y], 'pendown':[0, lambda self: self.tw.canvas.setpen(True)], 'pensize':[0, lambda self: self.tw.canvas.pensize], 'penup':[0, lambda self: self.tw.canvas.setpen(False)], @@ -357,9 +310,12 @@ class LogoCode: self.scale = 33 + """ + Given a block to run... + """ def run_blocks(self, blk, blocks, run_flag): - for x in self.stacks.keys(): - self.stacks[x] = None + for k in self.stacks.keys(): + self.stacks[k] = None self.stacks['stack1'] = None self.stacks['stack2'] = None for b in blocks: @@ -368,26 +324,29 @@ class LogoCode: if b.name=='hat2': self.stacks['stack2'] = self.readline(self.blocks_to_code(b)) if b.name == 'hat': - if (b.connections[1] is not None): - text = b.connections[1].values[0] - self.stacks['stack3'+text] =\ + if b.connections[1] is not None: + self.stacks['stack3'+b.connections[1].values[0]] =\ self.readline(self.blocks_to_code(b)) code = self.blocks_to_code(blk) if run_flag is True: print "running code: %s" % (code) self.setup_cmd(code) - else: return code + else: + return code + """ + Convert a stack of blocks to pseudocode. + """ def blocks_to_code(self, blk): if blk is None: return ['%nothing%'] code = [] dock = blk.docks[0] if len(dock)>4: - code.append(dock[4]) + code.append(dock[4]) # There could be a '(' or '['. if blk.primitive is not None: code.append(blk.primitive) - elif len(blk.values)>0: + elif len(blk.values)>0: # Extract the value from content blocks. if blk.name=='number': try: code.append(float(blk.values[0])) @@ -416,12 +375,12 @@ class LogoCode: else: code.append('#saudio_None') else: - print "%s had nothing as a value" % (blk.name) + print "%s had no primitive." % (blk.name) return ['%nothing%'] else: - print "%s had no value" % (blk.name) + print "%s had no value." % (blk.name) return ['%nothing%'] - for i in range(1,len(blk.connections)): + for i in range(1, len(blk.connections)): b = blk.connections[i] dock = blk.docks[i] if len(dock)>4: @@ -433,33 +392,54 @@ class LogoCode: code.append('%nothing%') return code - def intern(self, str): - if str in self.oblist: return self.oblist[str] - sym = symbol(str) - self.oblist[str] = sym - return sym - + """ + Execute the psuedocode. + """ + def setup_cmd(self, str): + self.tw.active_turtle.hide() # Hide the turtle while we are running. + self.procstop = False + list = self.readline(str) + # print list + self.step = self.start_eval(list) + + """ + Convert the pseudocode into a list of commands. + """ def readline(self, line): res = [] while line: token = line.pop(0) - if isNumberType(token): res.append(token) - elif token.isdigit(): res.append(float(token)) + if isNumberType(token): + res.append(token) + elif token.isdigit(): + res.append(float(token)) elif token[0]=='-' and token[1:].isdigit(): res.append(-float(token[1:])) - elif token[0] == '"': res.append(token[1:]) - elif token[0:2] == "#s": res.append(token[2:]) - elif token == '[': res.append(self.readline(line)) - elif token == ']': return res - else: res.append(self.intern(token)) + elif token[0] == '"': + res.append(token[1:]) + elif token[0:2] == "#s": + res.append(token[2:]) + elif token == '[': + res.append(self.readline(line)) + elif token == ']': + return res + else: + res.append(self.intern(token)) return res - def setup_cmd(self, str): - self.tw.active_turtle.hide() - self.procstop=False - list = self.readline(str) - self.step = self.start_eval(list) - + """ + Add the object to the object list. + """ + def intern(self, str): + if str in self.oblist: + return self.oblist[str] + sym = symbol(str) + self.oblist[str] = sym + return sym + + """ + Step through the list. + """ def start_eval(self, list): self.icall(self.evline, list) yield True @@ -467,12 +447,23 @@ class LogoCode: self.tw.activity.stop_button.set_icon("stopitoff") yield False + """ + Add a function to the program stack. + """ + def icall(self, fcn, *args): + self.istack.append(self.step) + self.step = fcn(*(args)) + + """ + Evaluate a line of code from the list. + """ def evline(self, list): oldiline = self.iline self.iline = list[:] self.arglist = None + # print "evline: %s" % (self.iline) while self.iline: - if self.tw.step_time > 0: + if self.tw.step_time > 0: # show the turtle during idle time self.tw.active_turtle.show() endtime = millis()+self.an_int(self.tw.step_time)*100 while millis()<endtime: @@ -490,27 +481,38 @@ class LogoCode: raise logoerror(str(self.iresult)) self.iline = oldiline self.ireturn() - display_coordinates(self.tw) + self.tw.display_coordinates() yield True + """ + Evaluate the next token on the line. + """ def eval(self, infixarg=False): token = self.iline.pop(0) + # print "eval: %s" % (str(token)) if type(token) == self.symtype: - self.icall(self.evalsym, token); yield True + self.icall(self.evalsym, token) + yield True res = self.iresult - else: res = token + else: + res = token if not infixarg: while self.infixnext(): - self.icall(self.evalinfix, res); yield True + self.icall(self.evalinfix, res) + yield True res = self.iresult self.ireturn(res) yield True + """ + Process symbols. + """ def evalsym(self, token): self.debug_trace(token) self.undefined_check(token) oldcfun, oldarglist = self.cfun, self.arglist self.cfun, self.arglist = token, [] + # print " evalsym: %s %s" % (str(self.cfun), str(self.arglist)) if token.nargs == None: raise logoerror("#noinput") for i in range(token.nargs): @@ -559,6 +561,36 @@ class LogoCode: return False return self.iline[0].name in ['+', '-', '*', '/','%','and','or'] + def ufuncall(self, body): + ijmp(self.evline, body) + yield True + + def doevalstep(self): + starttime = millis() + try: + while (millis()-starttime)<120: + try: + if self.step is not None: + self.step.next() + else: # TODO: where is doevalstep getting called with None? + print "step is None" + return False + except StopIteration: + self.tw.active_turtle.show() + return False + except logoerror, e: + self.showlabel(str(e)[1:-1]) + self.tw.active_turtle.show() + return False + return True + + def ireturn(self, res=None): + self.step = self.istack.pop() + self.iresult = res + + def ijmp(self, fcn, *args): + self.step = fcn(*(args)) + def debug_trace(self, token): if self.trace: if token.name in PALETTES[PALETTE_NAMES.index('turtle')]: @@ -686,10 +718,9 @@ class LogoCode: def prim_stopstack(self): self.procstop = True - def ufuncall(self, body): - ijmp(self.evline, body) - yield True - + def heap_print(self): + self.showlabel(self.heap) + def an_int(self, n): if type(n) == int: return n @@ -729,6 +760,89 @@ class LogoCode: else: return y + def status_print(self, n): + if type(n) == str or type(n) == unicode: + # show title for Journal entries + if n[0:6] == 'media_': + try: + dsobject = datastore.get(n[6:]) + self.showlabel(dsobject.metadata['title']) + dsobject.destroy() + except: + self.showlabel(n) + else: + self.showlabel(n) + elif type(n) == int: + self.showlabel(n) + else: + self.showlabel(round_int(n)) + + def kbinput(self): + if len(self.tw.keypress) == 1: + self.keyboard = ord(self.tw.keypress[0]) + else: + try: + self.keyboard = {'Escape': 27, 'space': 32, ' ': 32, + 'Return': 13, \ + 'KP_Up': 2, 'KP_Down': 4, 'KP_Left': 1, \ + 'KP_Right': 3,}[self.tw.keypress] + except: + self.keyboard = 0 + self.tw.keypress = "" + + def showlabel(self, label): + if label=='#nostack': + shp = 'nostack' + label='' + elif label=='#noinput': + shp = 'noinput' + label='' + elif label=='#emptyheap': + shp = 'emptyheap' + label='' + elif label=='#emptybox': + shp = 'emptybox' + label=' '+self.nobox + elif label=='#nomedia': + shp = 'nomedia' + label='' + elif label=='#nocode': + shp = 'nocode' + label='' + elif label=='#syntaxerror': + shp = 'syntaxerror' + label='' + elif label=='#overflowerror': + shp = 'overflowerror' + label='' + elif label=='#notanumber': + shp = 'overflowerror' + label='' + else: + shp = 'status' + self.tw.status_spr.set_shape(self.tw.status_shapes[shp]) + self.tw.status_spr.set_label(label) + self.tw.status_spr.set_layer(STATUS_LAYER) + + def setbox(self, name,val): + self.boxes[name]=val + + def push_heap(self, val): + self.heap.append(val) + + def pop_heap(self): + try: + return self.heap.pop(-1) + except: + raise logoerror ("#emptyheap") + + def empty_heap(self): + self.heap = [] + + """ + Everything below is related to multimedia commands + """ + def show_picture(self, media, x, y, w, h): if media == "" or media[6:] == "": pass @@ -738,7 +852,6 @@ class LogoCode: try: dsobject = datastore.get(media[6:]) except: - # raise logoerror("#nomedia") print "Couldn't open media object %s" % (media[6:]) if movie_media_type(dsobject.file_path[-4:]): play_movie_from_file(self, @@ -1043,123 +1156,3 @@ class LogoCode: y = self.tw.canvas.height/2-int(self.tw.canvas.ycor) self.tw.canvas.draw_text(string,x,y-15,int(fsize),self.tw.canvas.width) - def hideblocks(self): - self.tw.hide = False # force hide - self.tw.hideshow_button() - # TODO: how do we do this with the new toolbar? - #for i in self.tw.selbuttons: - # hide(i) - if self.tw.running_sugar: - self.tw.activity.do_hide() - - def doevalstep(self): - starttime = millis() - try: - while (millis()-starttime)<120: - try: - if self.step is not None: - self.step.next() - else: # TODO: where is doevalstep getting called with None? - print "step is None" - return False - except StopIteration: - self.tw.active_turtle.show() - return False - except logoerror, e: - self.showlabel(str(e)[1:-1]) - self.tw.active_turtle.show() - return False - return True - - def icall(self, fcn, *args): - self.istack.append(self.step) - self.step = fcn(*(args)) - - def ireturn(self, res=None): - self.step = self.istack.pop() - self.iresult = res - - def ijmp(self, fcn, *args): - self.step = fcn(*(args)) - - def heap_print(self): - self.showlabel(self.heap) - - def status_print(self, n): - if type(n) == str or type(n) == unicode: - # show title for Journal entries - if n[0:6] == 'media_': - try: - dsobject = datastore.get(n[6:]) - self.showlabel(dsobject.metadata['title']) - dsobject.destroy() - except: - self.showlabel(n) - else: - self.showlabel(n) - elif type(n) == int: - self.showlabel(n) - else: - self.showlabel(round_int(n)) - - def kbinput(self): - if len(self.tw.keypress) == 1: - self.keyboard = ord(self.tw.keypress[0]) - else: - try: - self.keyboard = {'Escape': 27, 'space': 32, ' ': 32, - 'Return': 13, \ - 'KP_Up': 2, 'KP_Down': 4, 'KP_Left': 1, \ - 'KP_Right': 3,}[self.tw.keypress] - except: - self.keyboard = 0 - self.tw.keypress = "" - - def showlabel(self, label): - if label=='#nostack': - shp = 'nostack' - label='' - elif label=='#noinput': - shp = 'noinput' - label='' - elif label=='#emptyheap': - shp = 'emptyheap' - label='' - elif label=='#emptybox': - shp = 'emptybox' - label=' '+self.nobox - elif label=='#nomedia': - shp = 'nomedia' - label='' - elif label=='#nocode': - shp = 'nocode' - label='' - elif label=='#syntaxerror': - shp = 'syntaxerror' - label='' - elif label=='#overflowerror': - shp = 'overflowerror' - label='' - elif label=='#notanumber': - shp = 'overflowerror' - label='' - else: - shp = 'status' - self.tw.status_spr.set_shape(self.tw.status_shapes[shp]) - self.tw.status_spr.set_label(label) - self.tw.status_spr.set_layer(STATUS_LAYER) - - def setbox(self, name,val): - self.boxes[name]=val - - def push_heap(self, val): - self.heap.append(val) - - def pop_heap(self): - try: - return self.heap.pop(-1) - except: - raise logoerror ("#emptyheap") - - def empty_heap(self): - self.heap = [] @@ -139,3 +139,38 @@ def save_picture(canvas, fname): 0, 0, 0, 0, canvas.width, canvas.height) pixbuf.save(fname, 'png') + +def get_pixbuf_from_journal(dsobject, w, h): + try: + pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(dsobject.file_path, + int(w),int(h)) + except: + try: + pixbufloader = \ + gtk.gdk.pixbuf_loader_new_with_mime_type('image/png') + pixbufloader.set_size(min(300,int(w)),min(225,int(h))) + pixbufloader.write(dsobject.metadata['preview']) + pixbufloader.close() + pixbuf = pixbufloader.get_pixbuf() + except: + pixbuf = None + return pixbuf + +def movie_media_type(suffix): + if suffix.replace('.','') in ['ogv','vob','mp4','wmv','mov', 'mpeg']: + return True + return False + +def audio_media_type(suffix): + if suffix.replace('.','') in ['ogg', 'oga', 'm4a']: + return True + return False + +def round_int(n): + if int(float(n)) == n: + return int(n) + else: + nn = int(float(n+0.05)*10)/10. + if int(float(nn)) == nn: + return int(nn) + return nn diff --git a/tawindow.py b/tawindow.py index 25ee306..4a7f72d 100644 --- a/tawindow.py +++ b/tawindow.py @@ -49,8 +49,7 @@ except: from gettext import gettext as _ from tautils import * from sprite_factory import SVG, svg_str_to_pixbuf -from talogo import LogoCode, stop_logo, get_pixbuf_from_journal,\ - display_coordinates, movie_media_type, audio_media_type +from talogo import LogoCode, stop_logo from tacanvas import TurtleGraphics from sprites import Sprites, Sprite from block import Blocks, Block @@ -189,7 +188,7 @@ class TurtleArtWindow(): if self.status_spr is not None: self.status_spr.set_layer(HIDE_LAYER) self.lc.clear() - display_coordinates(self) + self.display_coordinates() """ Stop button @@ -198,16 +197,17 @@ class TurtleArtWindow(): stop_logo(self) """ - Change the icon for user-defined blocks after Python code is loaded + Change the icon for user-defined blocks after Python code is loaded. """ def set_userdefined(self): for blk in self.just_blocks(): if blk.name == 'nop': - blk.spr.set_image(self.media_shapes['pythonon'], 1, 15, 8) + blk.spr.set_image(self.media_shapes['pythonon'], 1, + PYTHON_X, PYTHON_Y) self.nop = 'pythonloaded' """ - hideshow button + Hide/show button """ def hideshow_button(self): if self.hide is False: @@ -223,7 +223,7 @@ class TurtleArtWindow(): self.canvas.canvas.inval() """ - hideshow_palette + Hide or show palette """ def hideshow_palette(self, state): if state is False: @@ -238,7 +238,7 @@ class TurtleArtWindow(): self.show_palette() """ - show palette + Show palette """ def show_palette(self): self.show_toolbar_palette(0) @@ -252,6 +252,15 @@ class TurtleArtWindow(): self.palette = False """ + Callback from 'hide blocks' block + """ + def hideblocks(self): + self.hide = False + self.hideshow_button() + if self.running_sugar: + self.activity.do_hide() + + """ Where is the mouse event? """ def xy(self, event): @@ -973,7 +982,7 @@ class TurtleArtWindow(): self.canvas.ycor = self.canvas.canvas._height/2-ty-30+cy self.canvas.move_turtle() if self.running_sugar: - display_coordinates(self) + self.display_coordinates() self.selected_turtle = None return @@ -1347,7 +1356,7 @@ class TurtleArtWindow(): self.canvas.xcor += dx self.canvas.ycor += dy self.canvas.move_turtle() - display_coordinates(self) + self.display_coordinates() self.selected_turtle = None """ @@ -1461,7 +1470,7 @@ class TurtleArtWindow(): Process data (from a file or clipboard) into blocks """ def process_data(self, data): - # Create the blocks. + # Create the blocks (or turtle). blocks = [] t = 0 for b in data: @@ -1474,14 +1483,22 @@ class TurtleArtWindow(): # Make the connections. for i in range(len(blocks)): cons=[] - # Ugly corner case to support old-style booleans - if blocks[i].connections == 'check': + # Normally, it is simply a matter of copying the connections. + if blocks[i].connections == None: + for c in data[i][4]: + if c is None: + cons.append(None) + else: + cons.append(blocks[c]) + elif blocks[i].connections == 'check': + # Ugly corner case is to convert old-style booleans op. cons.append(None) # Add an extra connection. for c in data[i][4]: if c is None: cons.append(None) else: cons.append(blocks[c]) + # If the boolean op was connected, readjust the plumbing. if data[i][4][0] is not None: c = data[i][4][0] cons[0] = blocks[data[c][4][0]] @@ -1493,30 +1510,34 @@ class TurtleArtWindow(): blocks[c].connections[0] = blocks[i] blocks[c].connections[3] = None else: - print "WARNING: could not look into the future" - # Normally, it is simply a matter of copying the connections. + # Connection was to a block we haven't seen yet. + print "WARNING: dock check couldn't see the future" else: - for c in data[i][4]: - if c is None: - cons.append(None) - else: - cons.append(blocks[c]) + print "WARNING: unknown connection state %s" %\ + (str(blocks[i].connections)) blocks[i].connections = cons[:] - # Adjust the x,y positions, as block sizes and shapes may have changed. + # Block sizes and shapes may have changed. for b in blocks: - (sx, sy) = b.spr.get_xy() - for i, c in enumerate(b.connections): - if i>0 and c is not None: - bdock = b.docks[i] - for j in range(len(c.docks)): - if c.connections[j] == b: - cdock = c.docks[j] - nx, ny = sx+bdock[2]-cdock[2], sy+bdock[3]-cdock[3] - c.spr.move((nx, ny)) - - # - # Restore individual blocks from saved state - # + self._adjust_dock_positions(b) + + """ + Adjust the dock x,y positions + """ + def _adjust_dock_positions(self, blk): + (sx, sy) = blk.spr.get_xy() + for i, c in enumerate(blk.connections): + if i>0 and c is not None: + bdock = blk.docks[i] + for j in range(len(c.docks)): + if c.connections[j] == blk: + cdock = c.docks[j] + nx, ny = sx+bdock[2]-cdock[2], sy+bdock[3]-cdock[3] + c.spr.move((nx, ny)) + self._adjust_dock_positions(c) + + """ + Restore individual blocks from saved state + """ def load_block(self, b): # A block is saved as: (i, (btype, value), x, y, (c0,... cn)) # The x,y position is saved/loaded for backward compatibility @@ -1538,14 +1559,10 @@ class TurtleArtWindow(): if btype in OLD_DOCK: check_dock = True - print "WARNING: will need to preform dock check" else: check_dock = False if OLD_NAMES.has_key(btype): - print "%s -> %s" % (btype, OLD_NAMES[btype]) btype = OLD_NAMES[btype] - else: - print "%s" % (btype) blk = Block(self.block_list, self.sprite_list, btype, b[2]+self.canvas.cx, b[3]+self.canvas.cy, 'block', values) @@ -1615,9 +1632,9 @@ class TurtleArtWindow(): blk.connections = 'check' return blk - # - # Restore a turtle from its saved state - # + """ + Restore a turtle from its saved state + """ def load_turtle(self, b): id, name, xcor, ycor, heading, color, shade, pensize = b self.canvas.setxy(xcor, ycor) @@ -1626,15 +1643,15 @@ class TurtleArtWindow(): self.canvas.setshade(shade) self.canvas.setpensize(pensize) - # - # Start a new project with a 'start' brick - # + """ + Start a new project with a 'start' brick + """ def load_start(self): self.process_data([[0, "start", 218, 224, [None, None]]]) - # - # Start a project to a file - # + """ + Start a project to a file + """ def save_file(self): if self.save_folder is not None: self.load_save_folder = self.save_folder @@ -1649,9 +1666,9 @@ class TurtleArtWindow(): data_to_file(data, fname+'.ta') self.save_file_name = os.path.basename(fname) - # - # Pack the project (or stack) into a data stream to be serialized - # + """ + Pack the project (or stack) into a data stream to be serialized + """ def assemble_data_to_save(self, save_turtle=True, save_project=True): # TODO: if save_project is False: just the current stack data = [] @@ -1689,3 +1706,17 @@ class TurtleArtWindow(): self.canvas.pensize)) return data + """ + Display the coordinates of the current turtle + """ + def display_coordinates(self): + x = round_int(self.canvas.xcor/self.coord_scale) + y = round_int(self.canvas.ycor/self.coord_scale) + h = round_int(self.canvas.heading) + if self.running_sugar: + self.activity.coordinates_label.set_text("%s: %d %s: %d %s: %d" % ( + _("xcor"), x, _("ycor"), y, _("heading"), h)) + self.activity.coordinates_label.show() + else: + self.win.set_title("%s — %s: %d %s: %d %s: %d" % (_("Turtle Art"), + _("xcor"), x, _("ycor"), y, _("heading"), h)) |