diff options
-rwxr-xr-x | MANIFEST | 52 | ||||
-rwxr-xr-x | NEWS | 3 | ||||
-rwxr-xr-x | TurtleArtActivity.py | 62 | ||||
-rwxr-xr-x | activity/activity.info | 2 | ||||
-rwxr-xr-x | arrow.gif | bin | 1251 -> 0 bytes | |||
-rwxr-xr-x | icons/stock-open.svg | 29 | ||||
-rwxr-xr-x | logo.py | 361 | ||||
-rwxr-xr-x | myblocks/1input.gif | bin | 2517 -> 0 bytes | |||
-rwxr-xr-x | myblocks/1inputmask.gif | bin | 244 -> 0 bytes | |||
-rwxr-xr-x | myblocks/2inputs.gif | bin | 3565 -> 0 bytes | |||
-rwxr-xr-x | myblocks/2inputsmask.gif | bin | 322 -> 0 bytes | |||
-rwxr-xr-x | myblocks/3inputs.gif | bin | 3090 -> 0 bytes | |||
-rwxr-xr-x | myblocks/3inputsmask.gif | bin | 250 -> 0 bytes | |||
-rwxr-xr-x | myblocks/boutput.gif | bin | 2746 -> 0 bytes | |||
-rwxr-xr-x | myblocks/boutputmask.gif | bin | 209 -> 0 bytes | |||
-rwxr-xr-x | myblocks/global.gif | bin | 1951 -> 0 bytes | |||
-rwxr-xr-x | myblocks/global1.gif | bin | 1721 -> 0 bytes | |||
-rwxr-xr-x | myblocks/global1mask.gif | bin | 133 -> 0 bytes | |||
-rwxr-xr-x | myblocks/globalmask.gif | bin | 140 -> 0 bytes | |||
-rwxr-xr-x | myblocks/line.gif | bin | 264 -> 0 bytes | |||
-rwxr-xr-x | myblocks/linemask.gif | bin | 124 -> 0 bytes | |||
-rwxr-xr-x | myblocks/mystuffbg.gif | bin | 1335 -> 0 bytes | |||
-rwxr-xr-x | myblocks/mystuffgroup.gif | bin | 5199 -> 0 bytes | |||
-rwxr-xr-x | myblocks/mystuffmask.gif | bin | 1091 -> 0 bytes | |||
-rwxr-xr-x | myblocks/opwith1ip.gif | bin | 1423 -> 0 bytes | |||
-rwxr-xr-x | myblocks/opwith1ipb.gif | bin | 1437 -> 0 bytes | |||
-rwxr-xr-x | myblocks/opwith1ipbmask.gif | bin | 154 -> 0 bytes | |||
-rwxr-xr-x | myblocks/opwith1ipmask.gif | bin | 161 -> 0 bytes | |||
-rwxr-xr-x | myblocks/output.gif | bin | 2060 -> 0 bytes | |||
-rwxr-xr-x | myblocks/output1.gif | bin | 1966 -> 0 bytes | |||
-rwxr-xr-x | myblocks/output1mask.gif | bin | 133 -> 0 bytes | |||
-rwxr-xr-x | myblocks/outputmask.gif | bin | 140 -> 0 bytes | |||
-rwxr-xr-x | myblocks/procedure.gif | bin | 2356 -> 0 bytes | |||
-rwxr-xr-x | myblocks/proceduremask.gif | bin | 232 -> 0 bytes | |||
-rwxr-xr-x | myblocks/setglobal.gif | bin | 3193 -> 0 bytes | |||
-rwxr-xr-x | myblocks/setglobalmask.gif | bin | 270 -> 0 bytes | |||
-rwxr-xr-x | myblocks/start.gif | bin | 2525 -> 0 bytes | |||
-rwxr-xr-x | myblocks/startmask.gif | bin | 276 -> 0 bytes | |||
-rwxr-xr-x | samples/sunrise.png | bin | 0 -> 255395 bytes | |||
-rwxr-xr-x | samples/sunrise.ta | 491 | ||||
-rwxr-xr-x | sprites.py | 120 | ||||
-rwxr-xr-x | ta.py | 563 | ||||
-rwxr-xr-x | talogo.py | 342 | ||||
-rwxr-xr-x | talogo.pyc | bin | 0 -> 18944 bytes | |||
-rwxr-xr-x | taproject.py | 137 | ||||
-rwxr-xr-x | taproject.pyc | bin | 0 -> 6393 bytes | |||
-rwxr-xr-x | tasetup.py (renamed from turtlesetup.py) | 106 | ||||
-rwxr-xr-x | tasetup.pyc | bin | 0 -> 6096 bytes | |||
-rwxr-xr-x | tasprites.py | 112 | ||||
-rwxr-xr-x | tasprites.pyc | bin | 0 -> 5305 bytes | |||
-rwxr-xr-x | taturtle.py | 174 | ||||
-rwxr-xr-x | taturtle.pyc | bin | 0 -> 8921 bytes | |||
-rwxr-xr-x | tawindow.py | 360 | ||||
-rwxr-xr-x | tawindow.pyc | bin | 0 -> 13715 bytes | |||
-rwxr-xr-x | toolbar/project-.gif | bin | 3497 -> 0 bytes | |||
-rwxr-xr-x | toolbar/project.gif | bin | 6629 -> 0 bytes | |||
-rwxr-xr-x | toolbar/projectmask.gif | bin | 589 -> 0 bytes | |||
-rwxr-xr-x | turtle.py | 195 | ||||
-rwxr-xr-x | turtleart.py | 22 |
59 files changed, 1768 insertions, 1363 deletions
@@ -1,13 +1,13 @@ -arrow.gif -logo.py masknumber.gif -sprites.py status.gif setup.py -ta.py +talogo.py +taproject.py +tasprites.py +tasetup.py +taturtle.py +tawindow.py TurtleArtActivity.py -turtle.py -turtlesetup.py icons/stock-open.svg flow/flowgroup.gif flow/flowmask.gif @@ -19,45 +19,14 @@ flow/repeat.gif flow/stopstack.gif flow/vspace.gif flow/wait.gif -myblocks/1input.gif -myblocks/1inputmask.gif -myblocks/2inputs.gif -myblocks/2inputsmask.gif -myblocks/3inputs.gif -myblocks/3inputsmask.gif -myblocks/boutput.gif -myblocks/boutputmask.gif myblocks/box1.gif myblocks/box2.gif -myblocks/global1.gif -myblocks/global1mask.gif -myblocks/global.gif -myblocks/globalmask.gif myblocks/hat1.gif myblocks/hat2.gif -myblocks/line.gif -myblocks/linemask.gif -myblocks/myblocksgroup.gif -myblocks/myblocksmask.gif -myblocks/mystuffbg.gif -myblocks/mystuffgroup.gif -myblocks/mystuffmask.gif -myblocks/opwith1ipb.gif -myblocks/opwith1ipbmask.gif -myblocks/opwith1ip.gif -myblocks/opwith1ipmask.gif -myblocks/output1.gif -myblocks/output1mask.gif -myblocks/output.gif -myblocks/outputmask.gif -myblocks/procedure.gif -myblocks/proceduremask.gif -myblocks/setglobal.gif -myblocks/setglobalmask.gif myblocks/stack1.gif myblocks/stack2.gif -myblocks/start.gif -myblocks/startmask.gif +myblocks/myblocksgroup.gif +myblocks/myblocksmask.gif myblocks/storeinbox1.gif myblocks/storeinbox2.gif numbers/and.gif @@ -139,9 +108,6 @@ toolbar/eraseroff.gif toolbar/eraseron.gif toolbar/hideshowoff.gif toolbar/hideshowon.gif -toolbar/project-.gif -toolbar/project.gif -toolbar/projectmask.gif toolbar/stopitoff.gif toolbar/stopiton.gif turtle/arc.gif @@ -191,5 +157,7 @@ samples/squares.png samples/squares.ta samples/squiral.png samples/squiral.ta +samples/sunrise.png +samples/sunrise.ta samples/xo-man.png samples/xo-man.ta @@ -0,0 +1,3 @@ +5 + +* Multi instance happy diff --git a/TurtleArtActivity.py b/TurtleArtActivity.py index 6fc4b50..a892795 100755 --- a/TurtleArtActivity.py +++ b/TurtleArtActivity.py @@ -1,4 +1,4 @@ -import ta +import tawindow import pygtk pygtk.require('2.0') import gtk @@ -7,9 +7,22 @@ from socket import * import sys import gobject -serverHost = '192.168.1.101' +serverHost = '192.168.1.102' serverPort = 5647 +def debug_init(): + s = socket(AF_INET, SOCK_STREAM) # create a TCP socket + s.connect((serverHost, serverPort)) # connect to server on the port + sys.stdout = s.makefile() + sys.stderr = sys.stdout + gobject.timeout_add(100, debug_tick) + +def debug_tick(): + sys.stdout.flush() + return True + +#debug_init() + import sugar from sugar.activity import activity from sugar.activity import registry @@ -18,11 +31,9 @@ from sugar.datastore import datastore from sugar import profile from gettext import gettext as _ - class TurtleArtActivity(activity.Activity): def __init__(self, handle): super(TurtleArtActivity,self).__init__(handle) -# self.debug_init() self.gamename = 'turtleart' self.set_title("TurtleArt") @@ -35,19 +46,25 @@ class TurtleArtActivity(activity.Activity): toolbox._activity_toolbar.keep.connect('clicked', self._keep_clicked_cb) # patch - self.connect('destroy', self._cleanup_cb) - canvas = gtk.EventBox() sugar.graphics.window.Window.set_canvas(self, canvas) + toolbox._activity_toolbar.title.grab_focus() + toolbox._activity_toolbar.title.select_region(0,0) - ta.init(canvas, activity.get_bundle_path(),self) + self.tw = tawindow.twNew(canvas, activity.get_bundle_path(),self) + self.tw.activity = self + self.tw.window.grab_focus() + + toolbox._activity_toolbar._update_title_sid = True + toolbox._activity_toolbar.title.connect('focus-out-event', self.update_title_cb, toolbox) # patch if self._jobject and self._jobject.file_path: self.read_file(self._jobject.file_path) - def _cleanup_cb(self, data=None): - return + def update_title_cb(self, widget, event, toolbox): + toolbox._activity_toolbar._update_title_cb() + toolbox._activity_toolbar._update_title_sid = True def _keep_clicked_cb(self, button): self.jobject_new_patch() @@ -62,8 +79,8 @@ class TurtleArtActivity(activity.Activity): del pngfd, tafd try: - ta.save_data(tafile) - ta.save_pict(pngfile) + tawindow.save_data(self.tw,tafile) + tawindow.save_pict(self.tw,pngfile) tar_fd.add(tafile, "ta_code.ta") tar_fd.add(pngfile, "ta_image.png") @@ -83,22 +100,12 @@ class TurtleArtActivity(activity.Activity): try: # We'll get 'ta_code.ta' and 'ta_image.png' tar_fd.extractall(tmpdir) - ta.load_files(os.path.join(tmpdir, 'ta_code.ta'), os.path.join(tmpdir, 'ta_image.png')) + tawindow.load_files(self.tw, os.path.join(tmpdir, 'ta_code.ta'), os.path.join(tmpdir, 'ta_image.png')) finally: shutil.rmtree(tmpdir) tar_fd.close() - def debug_init(self): - s = socket(AF_INET, SOCK_STREAM) # create a TCP socket - s.connect((serverHost, serverPort)) # connect to server on the port - sys.stdout = s.makefile() - sys.stderr = sys.stdout - gobject.timeout_add(100, self.debug_tick) - - def debug_tick(self): - sys.stdout.flush() - return True def jobject_new_patch(self): oldj = self._jobject @@ -117,6 +124,15 @@ class TurtleArtActivity(activity.Activity): error_handler=self._internal_jobject_error_cb) + def clear_journal(self): + jobjects, total_count = datastore.find({'activity': 'org.laptop.TurtleArtActivity'}) + print 'found', total_count, 'entries' + for jobject in jobjects[:-1]: + print jobject.object_id + datastore.delete(jobject.object_id) + + + class ProjectToolbar(gtk.Toolbar): def __init__(self, pc): gtk.Toolbar.__init__(self) @@ -131,6 +147,6 @@ class ProjectToolbar(gtk.Toolbar): def do_samples(self, button): - ta.load_file() + tawindow.load_file(self.activity.tw) # self.activity.jobject_new_patch() diff --git a/activity/activity.info b/activity/activity.info index 657c942..23d9be0 100755 --- a/activity/activity.info +++ b/activity/activity.info @@ -3,5 +3,5 @@ name = TurtleArt service_name = org.laptop.TurtleArtActivity class = TurtleArtActivity.TurtleArtActivity icon = activity-turtleart -activity_version = 4 +activity_version = 5 show_launcher = yes diff --git a/arrow.gif b/arrow.gif Binary files differdeleted file mode 100755 index 37640dc..0000000 --- a/arrow.gif +++ /dev/null diff --git a/icons/stock-open.svg b/icons/stock-open.svg new file mode 100755 index 0000000..463e91b --- /dev/null +++ b/icons/stock-open.svg @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ + <!ENTITY ns_svg "http://www.w3.org/2000/svg"> + <!ENTITY ns_xlink "http://www.w3.org/1999/xlink"> + <!ENTITY stroke_color "#ffffff"> +]> +<svg version="1.1" id="Icon" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="44.365" height="42.918" + viewBox="0 0 44.365 42.918" overflow="visible" enable-background="new 0 0 44.365 42.918" xml:space="preserve"> +<g> + <g> + <path fill="none" stroke="&stroke_color;" stroke-width="3.5" stroke-linejoin="round" d="M1.75,41.168h21.923 + c1.99,0,3.076-1.295,3.076-3.078V13.699c0-1.547-1.549-3.077-3.076-3.077H19.75"/> + </g> +</g> +<g> + <g> + <path fill="none" stroke="&stroke_color;" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round" d="M19.75,31.859 + c0,1.643-1.202,2.864-3.077,3.619L1.75,41.168V10.623l14.923-7.688c1.991-0.352,3.077,0.751,3.077,2.534V31.859z"/> + </g> +</g> +<line fill="none" stroke="&stroke_color;" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round" x1="7.538" y1="38.961" x2="7.538" y2="7.641"/> +<g> + + <line fill="none" stroke="&stroke_color;" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round" x1="42.615" y1="1.75" x2="32.537" y2="11.828"/> + <polyline fill="none" stroke="&stroke_color;" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round" points="33.322,2.539 + 42.615,1.75 41.826,11.043 "/> +</g> +</svg> diff --git a/logo.py b/logo.py deleted file mode 100755 index 1c4a460..0000000 --- a/logo.py +++ /dev/null @@ -1,361 +0,0 @@ -import re
-from time import clock
-from operator import isNumberType
-import random
-
-oblist = {}
-
-iline = None
-cfun = None
-arglist = None
-
-istack = []
-iresult = None
-step = None
-procstop = False
-
-boxes = {'box1': 0, 'box2': 0}
-stacks = {}
-
-utime_start = 0
-
-class symbol:
-
- def __init__(self, name):
- self.name = name
- self.nargs = None
- self.fcn = None
-
- def __str__(self): return self.name
- def __repr__(self): return '#'+self.name
-
-class logoerror(Exception):
- def __init__(self, value):
- self.value = value
- def __str__(self):
- return repr(self.value)
-
-
-def run_blocks(spr, blocks):
- stacks['stack1'] = None
- stacks['stack2'] = None
- for i in blocks:
- if i.proto.name=='hat1': stacks['stack1']= readline(blocks_to_code(i))
- if i.proto.name=='hat2': stacks['stack2']= readline(blocks_to_code(i))
- code = blocks_to_code(spr)
- print code
- setup_cmd(code)
-
-def blocks_to_code(spr):
- if spr==None: return ['%nothing%']
- code = []
- dock = spr.proto.docks[0]
- if len(dock)>4: code.append(dock[4])
- if spr.proto.primname != '': code.append(spr.proto.primname)
- else: code.append(float(spr.label))
- for i in range(1,len(spr.connections)):
- b = spr.connections[i]
- dock = spr.proto.docks[i]
- if len(dock)>4:
- for c in dock[4]: code.append(c)
- if b!=None: code.extend(blocks_to_code(b))
- elif spr.proto.docks[i][0] not in ['flow','numend','unavailable','logi-']:
- code.append('%nothing%')
- return code
-
-def intern(str):
- if str in oblist: return oblist[str]
- sym = symbol(str)
- oblist[str] = sym
- return sym
-
-
-def parseline(str):
- split = re.split(r"\s|([\[\]()])", str)
- return [x for x in split if x and x != ""]
-
-def readline(line):
- res = []
- while line:
- token = line.pop(0)
- 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 == '[': res.append(readline(line))
- elif token == ']': return res
- else: res.append(intern(token))
- return res
-
-
-def setup_cmd(str):
- global iline, step, procstop
- stopsignon(); procstop=False
- list = readline(str)
- step = start_eval(list)
-
-def start_eval(list):
- icall(evline, list); yield True
- yield False
-
-def evline(list):
- global cfun, arglist, iline
- oldiline = iline
- iline = list[:]
- arglist = None
- while iline:
- token = iline[0]
- if token==symopar: token=iline[1]
- icall(eval); yield True
- if procstop: break
- if iresult==None: continue
- raise logoerror("You don't say what to do with %s" % token)
- iline = oldiline
- ireturn(); yield True
-
-def eval(infixarg=False):
- token = iline.pop(0)
- if type(token) == symtype:
- icall(evalsym, token); yield True
- res = iresult
- else: res = token
- if not infixarg:
- while infixnext():
- icall(evalinfix, res); yield True
- res = iresult
- ireturn(res); yield True
-
-def evalsym(token):
- global cfun, arglist
- undefined_check(token)
- oldcfun, oldarglist = cfun, arglist
- cfun, arglist = token, []
- for i in range(token.nargs):
- no_args_check()
- icall(eval); yield True
- arglist.append(iresult)
- if cfun.rprim:
- if type(cfun.fcn)==listtype: icall(ufuncall, cfun.fcn); yield True
- else: icall(cfun.fcn, *arglist); yield True
- result = None
- else: result = cfun.fcn(*arglist)
- cfun, arglist = oldcfun, oldarglist
- if arglist!=None and result==None:
- raise logoerror("%s didn't output to %s" % (oldcfun.name, cfun.name))
- ireturn(result); yield True
-
-def evalinfix(firstarg):
- global cfun, arglist
- token = iline.pop(0)
- oldcfun, oldarglist = cfun, arglist
- cfun, arglist = token, [firstarg]
- no_args_check()
- icall(eval,True); yield True
- arglist.append(iresult)
- result = cfun.fcn(*arglist)
- cfun, arglist = oldcfun, oldarglist
- ireturn (result); yield True
-
-def infixnext():
- if len(iline)==0: return False
- if type(iline[0])!=symtype: return False
- return iline[0].name in ['+', '-', '*', '/','%','and','or']
-
-def undefined_check(token):
- if token.fcn != None: return False
- raise logoerror("I don't know how to %s" % token.name)
-
-
-def no_args_check():
- if iline and iline[0]!=symnothing : return
- raise logoerror("Not enough inputs to %s" % cfun.name)
-
-def prim_wait(time):
- turtle_spr.setlayer(630)
- endtime = millis()+an_int(time)*100
- while millis()<endtime:
- yield True
- turtle_spr.setlayer(100)
- ireturn(); yield True
-
-def prim_repeat(num, list):
- num = an_int(num)
- for i in range(num):
- icall(evline, list[:]); yield True
- if procstop: break
- ireturn(); yield True
-
-def prim_forever(list):
- while True:
- icall(evline, list[:]); yield True
- if procstop: break
- ireturn(); yield True
-
-def prim_if(bool, list):
- if bool: icall(evline, list[:]); yield True
- ireturn(); yield True
-
-def prim_ifelse(bool, list1,list2):
- if bool: ijmp(evline, list1[:]); yield True
- else: ijmp(evline, list2[:]); yield True
-
-def prim_opar(val):
- iline.pop(0)
- return val
-
-def prim_define(name, body):
- if type(name) != symtype: name = intern(name)
- name.nargs, name.fcn = 0, body
- name.rprim = True
-
-def prim_stack1():
- global procstop
- if stacks['stack1']==None: raise logoerror("stack1 undefined")
- icall(evline, stacks['stack1'][:]); yield True
- procstop = False
- ireturn(); yield True
-
-def prim_stack2():
- global procstop
- if stacks['stack2']==None: raise logoerror("stack2 undefined")
- icall(evline, stacks['stack2'][:]); yield True
- procstop = False
- ireturn(); yield True
-
-def prim_stopstack():
- global procstop
- procstop = True
-
-def prim_utimer():
- return float(int((clock()-utime_start)*1000000))
-
-def prim_resetut():
- global utime_start
- utime_start = clock()
-
-
-def ufuncall(body):
- ijmp(evline, body); yield True
-
-def an_int(n):
- try: return int(n)
- except: raise logoerror("%s doesn't like %s as input" % (cfun.name, str(n)))
-
-def a_float(n):
- try: return int(n)
- except: raise logoerror("%s doesn't like %s as input" % (cfun.name, str(n)))
-
-def defprim(name, args, fcn, rprim=False):
- sym = intern(name)
- sym.nargs, sym.fcn = args,fcn
- sym.rprim = rprim
-
-def init():
- global symtype, numtype, listtype, symnothing, symopar
- defprim('print', 1, lambda x:showlabel(int(float(x)*10)/10.))
-
- defprim('sum', 2, lambda x,y:x+y)
- defprim('+', None, lambda x,y:x+y)
- defprim('difference', 2, lambda x,y:x-y)
- defprim('-', None, lambda x,y:x-y)
- defprim('product', 2, lambda x,y:x*y)
- defprim('*', None, lambda x,y:x*y)
- defprim('quotient', 2, lambda x,y:x/y)
- defprim('/', None, lambda x,y:x/y)
- defprim('random', 2, lambda x,y: int(random.uniform(x,y)))
- defprim('greater?', 2, lambda x,y: float(x)>float(y))
- defprim('less?', 2, lambda x,y: float(x)<float(y))
- defprim('equal?', 2, lambda x,y: float(x)==float(y))
- defprim('and', None, lambda x,y:x&y)
- defprim('or', None, lambda x,y:x|y)
- defprim('not', 1, lambda x:not x)
- defprim('%', None, lambda x,y:x%y)
-
- defprim('clean', 0, turtle.clearscreen)
- defprim('forward', 1, turtle.forward)
- defprim('back', 1, lambda x: turtle.forward(-x))
- defprim('seth', 1, turtle.seth)
- defprim('right', 1, turtle.right)
- defprim('left', 1, lambda x:turtle.right(-x))
- defprim('heading', 0, lambda: turtle.heading)
- defprim('setxy', 2, turtle.setxy)
- defprim('arc', 2, turtle.arc)
- defprim('xcor', 0, lambda: turtle.xcor)
- defprim('ycor', 0, lambda: turtle.ycor)
-
- defprim('pendown', 0, lambda: turtle.setpen(True))
- defprim('penup', 0, lambda: turtle.setpen(False))
- defprim('(', 1, prim_opar)
- defprim('setcolor', 1, turtle.setcolor)
- defprim('setshade', 1, turtle.setshade)
- defprim('setpensize', 1, turtle.setpensize)
- defprim('fillscreen', 2, turtle.fillscreen)
- defprim('color', 0, lambda: turtle.color)
- defprim('shade', 0, lambda: turtle.shade)
- defprim('pensize', 0, lambda: turtle.pensize)
-
- defprim('wait', 1, prim_wait, True)
- defprim('repeat', 2, prim_repeat, True)
- defprim('forever', 1, prim_forever, True)
- defprim('if', 2, prim_if, True)
- defprim('ifelse', 3, prim_ifelse, True)
- defprim('stopstack', 0, prim_stopstack)
-
- defprim('stack1', 0, prim_stack1, True)
- defprim('stack2', 0, prim_stack2, True)
- defprim('box1', 0, lambda: boxes['box1'])
- defprim('box2', 0, lambda: boxes['box2'])
- defprim('storeinbox1', 1, lambda x: setbox('box1',x))
- defprim('storeinbox2', 1, lambda x: setbox('box2',x))
-
- defprim('define', 2, prim_define)
- defprim('resetut', 0, prim_resetut)
- defprim('utimer', 0, prim_utimer)
- defprim('nop', 0, lambda: None)
- defprim('start', 0, lambda: None)
-
- symtype = type(intern('print'))
- numtytpe = type(0.)
- listtype = type([])
-
- symnothing = intern('%nothing%')
- symopar = intern('(')
-
-def doevalstep():
- starttime = millis()
- try:
- while (millis()-starttime)<120:
- if not step.next(): stopsignoff(); return False
- except logoerror, e: showlabel(str(e)[1:-1]); stopsignoff(); return False
- return True
-
-def icall(fcn, *args):
- global step
- istack.append(step)
- step = fcn(*(args))
-
-def ireturn(res=None):
- global step, iresult
- step = istack.pop()
- iresult = res
-
-def ijmp(fcn, *args):
- global step
- step = fcn(*(args))
-
-def showlabel(l):
- status.setlabel(l)
- status.setlayer(710);
-
-def stopsignon():
- stopsign.setshape(stopsign.onshape)
- turtle_spr.setlayer(100)
-
-def stopsignoff():
- stopsign.setshape(stopsign.offshape)
- turtle_spr.setlayer(630)
-
-def setbox(name,val): boxes[name]=val
-def tyo(n): print n
-def millis(): return int(clock()*1000)
-
diff --git a/myblocks/1input.gif b/myblocks/1input.gif Binary files differdeleted file mode 100755 index 1c8b8bf..0000000 --- a/myblocks/1input.gif +++ /dev/null diff --git a/myblocks/1inputmask.gif b/myblocks/1inputmask.gif Binary files differdeleted file mode 100755 index c182222..0000000 --- a/myblocks/1inputmask.gif +++ /dev/null diff --git a/myblocks/2inputs.gif b/myblocks/2inputs.gif Binary files differdeleted file mode 100755 index 51195db..0000000 --- a/myblocks/2inputs.gif +++ /dev/null diff --git a/myblocks/2inputsmask.gif b/myblocks/2inputsmask.gif Binary files differdeleted file mode 100755 index 976b6d5..0000000 --- a/myblocks/2inputsmask.gif +++ /dev/null diff --git a/myblocks/3inputs.gif b/myblocks/3inputs.gif Binary files differdeleted file mode 100755 index b984637..0000000 --- a/myblocks/3inputs.gif +++ /dev/null diff --git a/myblocks/3inputsmask.gif b/myblocks/3inputsmask.gif Binary files differdeleted file mode 100755 index 7cae1e9..0000000 --- a/myblocks/3inputsmask.gif +++ /dev/null diff --git a/myblocks/boutput.gif b/myblocks/boutput.gif Binary files differdeleted file mode 100755 index 1ec435c..0000000 --- a/myblocks/boutput.gif +++ /dev/null diff --git a/myblocks/boutputmask.gif b/myblocks/boutputmask.gif Binary files differdeleted file mode 100755 index 4062726..0000000 --- a/myblocks/boutputmask.gif +++ /dev/null diff --git a/myblocks/global.gif b/myblocks/global.gif Binary files differdeleted file mode 100755 index a067b24..0000000 --- a/myblocks/global.gif +++ /dev/null diff --git a/myblocks/global1.gif b/myblocks/global1.gif Binary files differdeleted file mode 100755 index 204f6d1..0000000 --- a/myblocks/global1.gif +++ /dev/null diff --git a/myblocks/global1mask.gif b/myblocks/global1mask.gif Binary files differdeleted file mode 100755 index 519ac9b..0000000 --- a/myblocks/global1mask.gif +++ /dev/null diff --git a/myblocks/globalmask.gif b/myblocks/globalmask.gif Binary files differdeleted file mode 100755 index 6d2c42f..0000000 --- a/myblocks/globalmask.gif +++ /dev/null diff --git a/myblocks/line.gif b/myblocks/line.gif Binary files differdeleted file mode 100755 index 6d7ca55..0000000 --- a/myblocks/line.gif +++ /dev/null diff --git a/myblocks/linemask.gif b/myblocks/linemask.gif Binary files differdeleted file mode 100755 index 329e2ae..0000000 --- a/myblocks/linemask.gif +++ /dev/null diff --git a/myblocks/mystuffbg.gif b/myblocks/mystuffbg.gif Binary files differdeleted file mode 100755 index 3a3bc99..0000000 --- a/myblocks/mystuffbg.gif +++ /dev/null diff --git a/myblocks/mystuffgroup.gif b/myblocks/mystuffgroup.gif Binary files differdeleted file mode 100755 index 06b92fb..0000000 --- a/myblocks/mystuffgroup.gif +++ /dev/null diff --git a/myblocks/mystuffmask.gif b/myblocks/mystuffmask.gif Binary files differdeleted file mode 100755 index b03eccc..0000000 --- a/myblocks/mystuffmask.gif +++ /dev/null diff --git a/myblocks/opwith1ip.gif b/myblocks/opwith1ip.gif Binary files differdeleted file mode 100755 index ee81a67..0000000 --- a/myblocks/opwith1ip.gif +++ /dev/null diff --git a/myblocks/opwith1ipb.gif b/myblocks/opwith1ipb.gif Binary files differdeleted file mode 100755 index fc01937..0000000 --- a/myblocks/opwith1ipb.gif +++ /dev/null diff --git a/myblocks/opwith1ipbmask.gif b/myblocks/opwith1ipbmask.gif Binary files differdeleted file mode 100755 index 1d9b98b..0000000 --- a/myblocks/opwith1ipbmask.gif +++ /dev/null diff --git a/myblocks/opwith1ipmask.gif b/myblocks/opwith1ipmask.gif Binary files differdeleted file mode 100755 index d985329..0000000 --- a/myblocks/opwith1ipmask.gif +++ /dev/null diff --git a/myblocks/output.gif b/myblocks/output.gif Binary files differdeleted file mode 100755 index ec894e1..0000000 --- a/myblocks/output.gif +++ /dev/null diff --git a/myblocks/output1.gif b/myblocks/output1.gif Binary files differdeleted file mode 100755 index 72f0706..0000000 --- a/myblocks/output1.gif +++ /dev/null diff --git a/myblocks/output1mask.gif b/myblocks/output1mask.gif Binary files differdeleted file mode 100755 index 519ac9b..0000000 --- a/myblocks/output1mask.gif +++ /dev/null diff --git a/myblocks/outputmask.gif b/myblocks/outputmask.gif Binary files differdeleted file mode 100755 index 6d2c42f..0000000 --- a/myblocks/outputmask.gif +++ /dev/null diff --git a/myblocks/procedure.gif b/myblocks/procedure.gif Binary files differdeleted file mode 100755 index 1418e89..0000000 --- a/myblocks/procedure.gif +++ /dev/null diff --git a/myblocks/proceduremask.gif b/myblocks/proceduremask.gif Binary files differdeleted file mode 100755 index b8b7242..0000000 --- a/myblocks/proceduremask.gif +++ /dev/null diff --git a/myblocks/setglobal.gif b/myblocks/setglobal.gif Binary files differdeleted file mode 100755 index 0f4908b..0000000 --- a/myblocks/setglobal.gif +++ /dev/null diff --git a/myblocks/setglobalmask.gif b/myblocks/setglobalmask.gif Binary files differdeleted file mode 100755 index f654994..0000000 --- a/myblocks/setglobalmask.gif +++ /dev/null diff --git a/myblocks/start.gif b/myblocks/start.gif Binary files differdeleted file mode 100755 index b116f7b..0000000 --- a/myblocks/start.gif +++ /dev/null diff --git a/myblocks/startmask.gif b/myblocks/startmask.gif Binary files differdeleted file mode 100755 index fb2b9cd..0000000 --- a/myblocks/startmask.gif +++ /dev/null diff --git a/samples/sunrise.png b/samples/sunrise.png Binary files differnew file mode 100755 index 0000000..b796f24 --- /dev/null +++ b/samples/sunrise.png diff --git a/samples/sunrise.ta b/samples/sunrise.ta new file mode 100755 index 0000000..90467a2 --- /dev/null +++ b/samples/sunrise.ta @@ -0,0 +1,491 @@ +(lp0 +(I0 +S'hat1' +p1 +I224 +I79 +(lp2 +NaI1 +atp3 +a(I1 +S'setxy' +p4 +I236 +I129 +(lp5 +I0 +aI2 +aI3 +aI4 +atp6 +a(I2 +(S'number' +p7 +S'0' +p8 +tp9 +I310 +I138 +(lp10 +I1 +aNatp11 +a(I3 +(g7 +g8 +tp12 +I310 +I175 +(lp13 +I1 +aNatp14 +a(I4 +S'seth' +p15 +I236 +I205 +(lp16 +I1 +aI5 +aI8 +atp17 +a(I5 +S'random' +p18 +I310 +I195 +(lp19 +I4 +aI6 +aI7 +aNatp20 +a(I6 +(g7 +g8 +tp21 +I338 +I214 +(lp22 +I5 +aNatp23 +a(I7 +(g7 +S'360' +p24 +tp25 +I460 +I214 +(lp26 +I5 +aNatp27 +a(I8 +S'repeat' +p28 +I236 +I244 +(lp29 +I4 +aI33 +aI9 +aNatp30 +a(I9 +S'setcolor' +p31 +I331 +I293 +(lp32 +I8 +aI15 +aI10 +atp33 +a(I10 +S'forward' +p34 +I331 +I347 +(lp35 +I9 +aI20 +aI11 +atp36 +a(I11 +S'right' +p37 +I331 +I386 +(lp38 +I10 +aI17 +aI12 +atp39 +a(I12 +g31 +I331 +I425 +(lp40 +I11 +aI16 +aI13 +atp41 +a(I13 +g34 +I331 +I479 +(lp42 +I12 +aI18 +aI14 +atp43 +a(I14 +S'left' +p44 +I331 +I518 +(lp45 +I13 +aI19 +aNatp46 +a(I15 +g18 +I405 +I291 +(lp47 +I9 +aI29 +aI30 +aNatp48 +a(I16 +g18 +I405 +I423 +(lp49 +I12 +aI31 +aI32 +aNatp50 +a(I17 +g18 +I405 +I376 +(lp51 +I11 +aI23 +aI24 +aNatp52 +a(I18 +g18 +I405 +I469 +(lp53 +I13 +aI25 +aI26 +aNatp54 +a(I19 +g18 +I405 +I508 +(lp55 +I14 +aI27 +aI28 +aNatp56 +a(I20 +g18 +I405 +I337 +(lp57 +I10 +aI21 +aI22 +aNatp58 +a(I21 +(g7 +S'10' +p59 +tp60 +I433 +I356 +(lp61 +I20 +aNatp62 +a(I22 +(g7 +S'30' +p63 +tp64 +I555 +I356 +(lp65 +I20 +aNatp66 +a(I23 +(g7 +S'30' +p67 +tp68 +I433 +I395 +(lp69 +I17 +aNatp70 +a(I24 +(g7 +S'40' +p71 +tp72 +I555 +I395 +(lp73 +I17 +aNatp74 +a(I25 +(g7 +S'10' +p75 +tp76 +I433 +I488 +(lp77 +I18 +aNatp78 +a(I26 +(g7 +S'30' +p79 +tp80 +I555 +I488 +(lp81 +I18 +aNatp82 +a(I27 +(g7 +S'30' +p83 +tp84 +I433 +I527 +(lp85 +I19 +aNatp86 +a(I28 +(g7 +S'40' +p87 +tp88 +I555 +I527 +(lp89 +I19 +aNatp90 +a(I29 +S'box1' +p91 +I433 +I310 +(lp92 +I15 +aNatp93 +a(I30 +S'box2' +p94 +I555 +I310 +(lp95 +I15 +aNatp96 +a(I31 +g91 +I433 +I442 +(lp97 +I16 +aNatp98 +a(I32 +g94 +I555 +I442 +(lp99 +I16 +aNatp100 +a(I33 +(g7 +S'20' +p101 +tp102 +I322 +I253 +(lp103 +I8 +aNatp104 +a(I34 +S'fillscreen' +p105 +I791 +I52 +(lp106 +NaI35 +aI36 +aI37 +atp107 +a(I35 +(g7 +g8 +tp108 +I865 +I61 +(lp109 +I34 +aNatp110 +a(I36 +(g7 +g8 +tp111 +I865 +I98 +(lp112 +I34 +aNatp113 +a(I37 +S'setpensize' +p114 +I791 +I128 +(lp115 +I34 +aI38 +aI39 +atp116 +a(I38 +(g7 +S'6' +p117 +tp118 +I865 +I145 +(lp119 +I37 +aNatp120 +a(I39 +g28 +I791 +I182 +(lp121 +I37 +aI40 +aI41 +aNatp122 +a(I40 +(g7 +S'300' +p123 +tp124 +I877 +I191 +(lp125 +I39 +aNatp126 +a(I41 +S'storeinbox1' +p127 +I886 +I231 +(lp128 +I39 +aI42 +aI43 +atp129 +a(I42 +(g7 +S'15' +p130 +tp131 +I960 +I248 +(lp132 +I41 +aNatp133 +a(I43 +S'storeinbox2' +p134 +I886 +I285 +(lp135 +I41 +aI44 +aI45 +atp136 +a(I44 +(g7 +S'20' +p137 +tp138 +I960 +I302 +(lp139 +I43 +aNatp140 +a(I45 +S'stack1' +p141 +I886 +I339 +(lp142 +I43 +aI46 +atp143 +a(I46 +g127 +I886 +I378 +(lp144 +I45 +aI47 +aI48 +atp145 +a(I47 +(g7 +g8 +tp146 +I960 +I395 +(lp147 +I46 +aNatp148 +a(I48 +g134 +I886 +I432 +(lp149 +I46 +aI49 +aI50 +atp150 +a(I49 +(g7 +S'10' +p151 +tp152 +I960 +I449 +(lp153 +I48 +aNatp154 +a(I50 +g141 +I886 +I486 +(lp155 +I48 +aNatp156 +a(I-1 +S'turtle' +p157 +F666.32380685191617 +F230.72600351500273 +I60 +I3 +I50 +F6.0 +tp158 +a.
\ No newline at end of file diff --git a/sprites.py b/sprites.py deleted file mode 100755 index 245bac3..0000000 --- a/sprites.py +++ /dev/null @@ -1,120 +0,0 @@ -import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-import pango
-
-sprites = []
-gc = None
-window = None
-black = None
-
-class Sprite:
- def __init__(self,x,y,image,altlabel=False):
- self.x = x
- self.y = y
- self.setimage(image)
- self.label = None
- if altlabel: self.draw_label = self.draw_label2
- else: self.draw_label = self.draw_label1
-
- def setimage(self,image):
- self.image = image
- if isinstance(image,gtk.gdk.Pixbuf):
- self.width = self.image.get_width()
- self.height = self.image.get_height()
- else: self.width,self.height=image.get_size()
-
-
- def move(self,pos):
- self.inval()
- self.x,self.y = pos
- self.inval()
-
- def setshape(self,image):
- self.inval()
- self.setimage(image)
- self.inval()
-
- def setlayer(self, layer):
- if self in sprites: sprites.remove(self)
- self.layer = layer
- for i in range(len(sprites)):
- if layer < sprites[i].layer: sprites.insert(i, self); self.inval(); return
- sprites.append(self)
- self.inval()
-
- def hide(self):
- if self not in sprites: return
- self.inval()
- sprites.remove(self)
-
- def setlabel(self,label):
- self.label = label
- self.inval()
-
- def inval(self):
- area.invalidate_rect(gtk.gdk.Rectangle(self.x,self.y,self.width,self.height), False)
-
- def draw(self):
- if isinstance(self.image,gtk.gdk.Pixbuf): area.draw_pixbuf(gc, self.image, 0, 0, self.x, self.y)
- else: area.draw_drawable(gc,self.image,0,0,self.x,self.y,-1,-1)
- if self.label!=None: self.draw_label(self.label)
-
- def hit(self,pos):
- x,y = pos
- if x<self.x: return False
- if x>self.x+self.width: return False
- if y<self.y: return False
- if y>self.y+self.height: return False
- if isinstance(self.image,gtk.gdk.Pixmap): return True
- dx,dy = x-self.x, y-self.y
- return ord(self.image.get_pixels()[(dy*self.width+dx)*4+3]) == 255
-
- def draw_label1(self, label):
- fd = pango.FontDescription('Sans')
- fd.set_size(7*pango.SCALE)
- pl = window.create_pango_layout(str(label))
- pl.set_font_description(fd)
- swidth = pl.get_size()[0]/pango.SCALE
- sheight = pl.get_size()[1]/pango.SCALE
- centerx = self.x+self.width/2
- centery = self.y+self.height/2
- gc.set_foreground(black)
- area.draw_layout(gc,centerx-swidth/2,centery-sheight/2,pl)
-
- def draw_label2(self, label):
- fd = pango.FontDescription('Sans')
- fd.set_size(9*pango.SCALE)
- pl = window.create_pango_layout(str(label))
- pl.set_font_description(fd)
- sheight = pl.get_size()[1]/pango.SCALE
- centery = self.y+self.height/2
- gc.set_foreground(black)
- area.draw_layout(gc,self.x+50,centery-sheight/2,pl)
-
-
-def findsprite(pos):
- list = sprites[:]
- list.reverse()
- for s in list:
- if s.hit(pos): return s
- return None
-
-def redrawsprites():
- for s in sprites: s.draw()
-
-def getpixel(image,x,y):
- array = image.get_pixels()
- offset = (y*image.get_width()+x)*4
- r,g,b,a = ord(array[offset]),ord(array[offset+1]),ord(array[offset+2]),ord(array[offset+3])
- return (a<<24)+(b<<16)+(g<<8)+r
-
-def setspritecontext(w,a,g):
- global window,area,gc,black
- window=w
- area =a
- gc = g
- black = gc.get_colormap().alloc_color('black')
-
-def spritelist(): return sprites
\ No newline at end of file @@ -1,563 +0,0 @@ -import pygtk -pygtk.require('2.0') -import gtk -import gobject -import os -import os.path -import pickle -from math import atan2, pi -import sys - -from sprites import * -from turtlesetup import * -import logo -import turtle - -from sugar.datastore import datastore - -WIDTH=1200 -HEIGHT=780 - -DEGTOR = 2*pi/360 - -gc = None -area = None -window = None -draggroup = None -dragpos = (0,0) -current_category = None -category_spr = None -bgcolor = None -block_operation = None -selected_block = None -select_mask = None -firstkey = False -turtlecanvas = None -status_spr = None -turtle_spr = None -hidden_palette_icon = None -selbuttons = None - -load_save_folder = None -save_file_name = None - -# -# Button Press -# - -def buttonpress_cb(win, event): - global draggroup, dragpos, block_operation, selected_block - window.grab_focus() - block_operation = 'click' - if selected_block!=None: unselect() - status_spr.setlayer(400) - pos = xy(event) - x,y = pos - spr = findsprite(pos) - if spr==None: return True - if spr.type == 'selbutton': - select_category(spr) - elif spr.type == 'tool': - tooldispatch(spr) - elif spr.type == 'category': - block_selector_pressed(x,y) - elif spr.type == 'block': - block_pressed(event,x,y,spr) - elif spr.type == 'turtle': - turtle_pressed(x,y) - return True - -def block_pressed(event,x,y,spr): - global draggroup, dragpos, block_operation - dragpos = x-spr.x,y-spr.y - draggroup = findgroup(spr) - for b in draggroup: - b.setlayer(2000) - disconnect(spr) - -def turtle_pressed(x,y): - global draggroup, dragpos, block_operation - dx,dy = x-turtle_spr.x-30,y-turtle_spr.y-30 - if dx*dx+dy*dy > 200: dragpos = ('turn', turtle.heading-atan2(dy,dx)/DEGTOR,0) - else: dragpos = ('move', x-turtle_spr.x,y-turtle_spr.y) - draggroup = [turtle_spr] - -def block_selector_pressed(x,y): - if category_spr.image==hidden_palette_icon: - for i in selbuttons: i.setlayer(800) - select_category(selbuttons[0]) - else: - proto = get_proto_from_category(x,y) - if proto==None: return - if proto!='hide': new_block_from_category(proto,x,y) - else: - for i in selbuttons: i.hide() - category_spr.setshape(hidden_palette_icon) - - -def new_block_from_category(proto,x,y): - global draggroup, dragpos, block_operation - block_operation = 'new' - if proto == None: return True - newspr = Sprite(x-20,y-20,proto.image) - newspr.setlayer(2000) - dragpos = 20,20 - newspr.type = 'block' - newspr.proto = proto - if newspr.proto.name == 'number': newspr.label=100 - newspr.connections = [None]*len(proto.docks) - for i in range(len(proto.defaults)): - dock = proto.docks[i+1] - numproto = blockproto('number') - numdock = numproto.docks[0] - nx,ny = newspr.x+dock[2]-numdock[2],newspr.y+dock[3]-numdock[3] - argspr = Sprite(nx,ny,numproto.image) - argspr.type = 'block' - argspr.proto = numproto - argspr.label = str(proto.defaults[i]) - argspr.setlayer(2000) - argspr.connections = [newspr,None] - newspr.connections[i+1] = argspr - draggroup = findgroup(newspr) - -def get_proto_from_category(x,y): -# if current_category.mask == None: return current_category.blockprotos[(y-100)/30] - dx,dy = x-category_spr.x, y-category_spr.y, - pixel = getpixel(current_category.mask,dx,dy) - index = ((pixel%256)>>3)-1 -# print hex(pixel),index - if index==0: return 'hide' - index-=1 - if index>len(current_category.blockprotos): return None - return current_category.blockprotos[index] - -def select_category(spr): - global current_category - if current_category != None: - current_category.setshape(current_category.offshape) - spr.setshape(spr.onshape) - current_category = spr - category_spr.setshape(spr.group) - -# -# Mouse move -# - -def move_cb(win, event): - global block_operation - if draggroup == None: return True - block_operation = 'move' - spr = draggroup[0] - x,y = xy(event) - if spr.type=='block': - dragx, dragy = dragpos - dx,dy = x-dragx-spr.x,y-dragy-spr.y - for b in draggroup: - b.move((b.x+dx, b.y+dy)) - elif spr.type=='turtle': - type,dragx,dragy = dragpos - if type == 'move': - dx,dy = x-dragx-spr.x,y-dragy-spr.y - spr.move((spr.x+dx, spr.y+dy)) - else: - dx,dy = x-spr.x-30,y-spr.y-30 - turtle.seth(int(dragx+atan2(dy,dx)/DEGTOR+5)/10*10) - return True - - -# -# Button release -# - -def buttonrelease_cb(win, event): - global draggroup, selected_block,firstkey - if draggroup == None: return True - spr = draggroup[0] - x,y = xy(event) - if spr.type == 'turtle': - turtle.xcor = turtle_spr.x-turtlecanvas.x-turtle.width/2+30 - turtle.ycor = turtle.height/2-turtle_spr.y+turtlecanvas.y-30 - turtle.move_turtle() - draggroup = None - return True - if block_operation=='move' and category_spr.hit((x,y)): - for b in draggroup: b.hide() - draggroup = None - return True - snap_to_dock(draggroup) - for b in draggroup: b.setlayer(650) - draggroup = None - if block_operation=='click': - if spr.proto.name=='number': - selected_block = spr - select_mask.move((spr.x-6,spr.y-6)) - select_mask.setlayer(660) - firstkey = True - else: run_stack(spr) - return True - -def snap_to_dock(group): - d=200 - me = draggroup[0] - for mydockn in range(len(me.proto.docks)): - for you in blocks(): - if you in group: continue - for yourdockn in range(len(you.proto.docks)): - thisxy = dock_dx_dy(you,yourdockn,me,mydockn) - if magnitude(thisxy)>d: continue - d=magnitude(thisxy) - bestxy=thisxy - bestyou=you - bestyourdockn=yourdockn - bestmydockn=mydockn - if d<200: - for b in group: b.move((b.x+bestxy[0],b.y+bestxy[1])) - me.connections[bestmydockn]=bestyou - bestyou.connections[bestyourdockn]=me - -def dock_dx_dy(block1,dock1n,block2,dock2n): - if block1.connections[dock1n] != None: return (100,100) - if block2.connections[dock2n] != None: return (100,100) - dock1 = block1.proto.docks[dock1n] - dock2 = block2.proto.docks[dock2n] - d1type,d1dir,d1x,d1y=dock1[0:4] - d2type,d2dir,d2x,d2y=dock2[0:4] - if block1==block2: return (100,100) - if d1type!=d2type: return (100,100) - if d1dir==d2dir: return (100,100) - return (block1.x+d1x)-(block2.x+d2x),(block1.y+d1y)-(block2.y+d2y) - - -# -# Repaint -# - -def expose_cb(win, event): -# gc.set_foreground(bgcolor) -# area.draw_rectangle(gc, True, category_spr.x, 0, category_spr.width, HEIGHT) -# area.draw_rectangle(gc, True, 100, 100, 100, 100) - - redrawsprites() - return True - - -# -# Keyboard, new, load, save -# - -def keypress_cb(area, event): - global firstkey - keyname = gtk.gdk.keyval_name(event.keyval) -# print keyname - if (event.get_state()>k.gdk.CONTROL_MASK): - if keyname=="s": save_file() - if keyname=="k": clear_journal() - return True - if selected_block==None: return False - keyname = gtk.gdk.keyval_name(event.keyval) - if keyname in ['minus', 'period']: keyname = {'minus': '-', 'period': '.'}[keyname] - if len(keyname)>1: return True - oldnum = selected_block.label - if firstkey: newnum = numcheck(keyname,'0') - else: newnum = oldnum+keyname - selected_block.setlabel(numcheck(newnum,oldnum)) - firstkey = False - return True - -def numcheck(new, old): - if new in ['-', '.', '-.']: return new - if new=='.': return '0.' - try: float(new); return new - except ValueError,e : return old - -def unselect(): - global selected_block - if selected_block.label in ['-', '.', '-.']: select_block.setlabel('0') - select_mask.hide() - selected_block = None - -def new_project(): - global save_file_name - for b in blocks(): b.hide() - turtlecanvas.setlayer(600) - toolsprite('hideshow').setshape(toolsprs['hideshow'].offshape) - turtle.clearscreen() - save_file_name = None - -def load_file(): - '''Pop a load file dialog to allow the user to pick a .ta file to load. Guess that a .png file with the same name resides in the same directory and try to load that too.''' - global save_file_name - fname = get_load_name() - if fname==None: return - if fname[-3:]=='.ta': fname=fname[0:-3] - load_files(fname+'.ta', fname+'.png') - save_file_name = os.path.basename(fname) - -def load_files(ta_file, png_file=''): - '''Load the given TA code file and optional starting image as png file into a new project.''' - f = open(ta_file, "r") - data = pickle.load(f) - f.close() - new_project() - read_data(data) - try: - load_pict(png_file) - except: - '''the picture not loading is OK''' - print "load_files: picture didn't load" - pass - turtlecanvas.inval() - -def get_load_name(): - dialog = gtk.FileChooserDialog("Load...", None, - gtk.FILE_CHOOSER_ACTION_OPEN, - (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN, gtk.RESPONSE_OK)) - dialog.set_default_response(gtk.RESPONSE_OK) - return do_dialog(dialog) - -def read_data(data): - blocks = [] - for b in data: - if b[1]=='turtle': load_turtle(b) - else: spr = load_spr(b); blocks.append(spr) - for i in range(len(blocks)): - cons=[] - for c in data[i][4]: - if c==None: cons.append(None) - else: cons.append(blocks[c]) - blocks[i].connections = cons - -def load_spr(b): - btype, label = b[1],None - if type(btype)==type((1,2)): btype, label = btype - proto = blockproto(btype) - spr = Sprite(b[2]+turtlecanvas.x,b[3]+turtlecanvas.y, proto.image) - spr.type = 'block' - spr.proto = proto - if label!=None: spr.label=label - spr.setlayer(650) - return spr - -def load_turtle(b): - id, name, xcor, ycor, heading, color, shade, pensize = b - turtle.setxy(xcor, ycor) - turtle.seth(heading) - turtle.setcolor(color) - turtle.setshade(shade) - turtle.setpensize(pensize) - -def load_pict(fname): - pict = gtk.gdk.pixbuf_new_from_file(fname) - turtlecanvas.image.draw_pixbuf(gc, pict, 0, 0, 0, 0) - -def save_file(): - '''Pop a save file dialog to allow the user to pick a filename to save their project. Also saves the current art as a .png file with the same name.''' - global save_file_name - fname = get_save_name() - if fname==None: return - if fname[-3:]=='.ta': fname=fname[0:-3] - save_data(fname+".ta") - save_pict(fname+".png") - save_file_name = os.path.basename(fname) - -def get_save_name(): - dialog = gtk.FileChooserDialog("Save..", None, - gtk.FILE_CHOOSER_ACTION_SAVE, - (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE, gtk.RESPONSE_OK)) - dialog.set_default_response(gtk.RESPONSE_OK) - if save_file_name!=None: dialog.set_current_name(save_file_name+'.ta') - return do_dialog(dialog) - -def save_data(fname): - '''Writes the TurtleArt code to the given filename.''' - f = file(fname, "w") - bs = blocks() - data = [] - for i in range(len(bs)): bs[i].id=i - for b in bs: - name = b.proto.name - if name=='number': name=(name,b.label) - connections = [get_id(x) for x in b.connections] - data.append((b.id,name,b.x-turtlecanvas.x,b.y-turtlecanvas.y,connections)) - data.append((-1,'turtle', - turtle.xcor,turtle.ycor,turtle.heading, - turtle.color,turtle.shade,turtle.pensize)) - pickle.dump(data,f) - f.close() - -def save_pict(fname): - '''Writes the current art to the given filename.''' - tc = turtlecanvas - pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, tc.width, tc.height) - pixbuf.get_from_drawable(tc.image, tc.image.get_colormap(), 0, 0, 0, 0, tc.width, tc.height) - pixbuf.save(fname, 'png') - -def get_id(x): - if x==None: return None - return x.id - -def do_dialog(dialog): - global load_save_folder - result = None - filter = gtk.FileFilter() - filter.add_pattern("*.ta") - filter.set_name("Turtle Art") - dialog.add_filter(filter) - dialog.set_current_folder(load_save_folder) - response = dialog.run() - if response == gtk.RESPONSE_OK: - result = dialog.get_filename() - load_save_folder = dialog.get_current_folder() - dialog.destroy() - return result - -def clear_journal(): - jobjects, total_count = datastore.find({'activity': 'org.laptop.TurtleArtActivity'}) - print 'found', total_count, 'entries' - for jobject in jobjects[:-1]: - print jobject.object_id - datastore.delete(jobject.object_id) - - -# -# Block utilities -# - -def run_stack(spr): - top = find_top_block(spr) - logo.run_blocks(top, blocks()) - gobject.idle_add(logo.doevalstep) - - -def disconnect(b): - if b.connections[0]==None: return - b2=b.connections[0] - b2.connections[b2.connections.index(b)] = None - b.connections[0] = None - - -def findgroup(b): - group=[b] - for b2 in b.connections[1:]: - if b2!=None: group.extend(findgroup(b2)) - return group - -def find_top_block(spr): - while spr.connections[0]!=None: spr=spr.connections[0] - return spr - -def magnitude(pos): - x,y = pos - return x*x+y*y - -def xy(event): return map(int, event.get_coords()) -def blocks(): return [spr for spr in spritelist() if spr.type == 'block'] - - -# -# Toolbar -# - -def tooldispatch(spr): - if spr.blocktype == 'hideshow': hideshow_blocks(spr) - elif spr.blocktype == 'eraser': runtool(spr,turtle.clearscreen) - elif spr.blocktype == 'stopit': logo.step = just_stop() - -def just_stop(): yield False - -def runtool(spr,cmd): - spr.setshape(spr.onshape) - cmd() - gobject.timeout_add(250,spr.setshape,spr.offshape) - -def hideshow_blocks(spr): - if spr.image==spr.offshape: - for b in blocks(): b.setlayer(100) - spr.setshape(spr.onshape) - else: - for b in blocks(): b.setlayer(650) - spr.setshape(spr.offshape) - turtlecanvas.inval() - - -# -# Startup -# - -def init(top_window, path, parentwindow=None): - global gc, area, category_spr, bgcolor,turtlecanvas, select_mask - global status_spr, turtle_spr, selbuttons, hidden_palette_icon - global base_path, load_save_folder, window - window = top_window - base_path = path - if parentwindow is None: - parentwindow = top_window - - # remove any children of the window that Sugar may have added - #for widget in window.get_children(): window.remove(widget) - - #window.set_title("TurteArt") - window.connect("destroy", lambda w: gtk.main_quit()) - window.set_flags(gtk.CAN_FOCUS) - window.set_size_request(WIDTH, HEIGHT) - window.add_events(gtk.gdk.BUTTON_PRESS_MASK) - window.add_events(gtk.gdk.BUTTON_RELEASE_MASK) - window.add_events(gtk.gdk.POINTER_MOTION_MASK) - window.add_events(gtk.gdk.KEY_PRESS_MASK) - window.connect("expose-event", expose_cb) - window.connect("button-press-event", buttonpress_cb) - window.connect("button-release-event", buttonrelease_cb) - window.connect("motion-notify-event", move_cb) - window.connect("key_press_event", keypress_cb) - window.show() - parentwindow.show_all() - area = window.window - cursor_pix = gtk.gdk.pixbuf_new_from_file(os.path.join(base_path, 'arrow.gif')) - cursor = gtk.gdk.Cursor(area.get_display(), cursor_pix, 10, 0) - area.set_cursor(cursor) - gc = area.new_gc() - - setspritecontext(window,area,gc) - cm = gc.get_colormap() - bgcolor = cm.alloc_color('#fff8de') - -# who = Sprite(0,0,gtk.gdk.pixbuf_new_from_file('fullscreen.gif')) -# who.type = 'bg' -# who.setlayer(700) - - - turtlecanvas = Sprite(0,0,gtk.gdk.Pixmap(area,WIDTH,HEIGHT,-1)) - turtlecanvas.type = 'canvas' - turtlecanvas.setlayer(600) - select_mask = Sprite(100,100,gtk.gdk.pixbuf_new_from_file(os.path.join(base_path, 'masknumber.gif'))) - select_mask.type = 'selectmask' - status_spr = Sprite(0,790,gtk.gdk.pixbuf_new_from_file(os.path.join(base_path, 'status.gif')),True) - status_spr.type = 'status' - status_spr.setlayer(400) - turtle.shapelist = [gtk.gdk.pixbuf_new_from_file(os.path.join(base_path, 'shapes','t'+str(i)+'.gif')) - for i in range(36)] - turtle_spr = Sprite(100,100,turtle.shapelist[0]) - turtle_spr.type = 'turtle' - turtle_spr.setlayer(630) - turtle.init(window,turtlecanvas, turtle_spr, bgcolor) - hidden_palette_icon = gtk.gdk.pixbuf_new_from_file(os.path.join(base_path, 'toolbar','blocks-.gif')) - category_spr, selbuttons, default_category = setup_selectors(base_path) -# select_category(default_category) - for i in selbuttons: i.hide() - category_spr.setshape(hidden_palette_icon) - setup_toolbar() - logo.turtle = turtle - logo.turtle_spr = turtle_spr - logo.stopsign = toolsprite('stopit') - logo.status = status_spr - logo.init() - load_save_folder = os.path.join(base_path,'samples') - -def main(): - win = gtk.Window(gtk.WINDOW_TOPLEVEL) - init(win, os.path.abspath('.')) - gtk.main() - return 0 - -if __name__ == "__main__": - main() diff --git a/talogo.py b/talogo.py new file mode 100755 index 0000000..3198608 --- /dev/null +++ b/talogo.py @@ -0,0 +1,342 @@ +import re +from time import clock +from operator import isNumberType +import random +class taLogo: pass + +from taturtle import * + +procstop = False + +class symbol: + + def __init__(self, name): + self.name = name + self.nargs = None + self.fcn = None + + def __str__(self): return self.name + def __repr__(self): return '#'+self.name + +class logoerror(Exception): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + + +def run_blocks(lc, spr, blocks): + lc.stacks['stack1'] = None + lc.stacks['stack2'] = None + for i in blocks: + if i.proto.name=='hat1': lc.stacks['stack1']= readline(lc,blocks_to_code(i)) + if i.proto.name=='hat2': lc.stacks['stack2']= readline(lc,blocks_to_code(i)) + code = blocks_to_code(spr) + print code + setup_cmd(lc, code) + +def blocks_to_code(spr): + if spr==None: return ['%nothing%'] + code = [] + dock = spr.proto.docks[0] + if len(dock)>4: code.append(dock[4]) + if spr.proto.primname != '': code.append(spr.proto.primname) + else: code.append(float(spr.label)) + for i in range(1,len(spr.connections)): + b = spr.connections[i] + dock = spr.proto.docks[i] + if len(dock)>4: + for c in dock[4]: code.append(c) + if b!=None: code.extend(blocks_to_code(b)) + elif spr.proto.docks[i][0] not in ['flow','numend','unavailable','logi-']: + code.append('%nothing%') + return code + +def intern(lc, str): + if str in lc.oblist: return lc.oblist[str] + sym = symbol(str) + lc.oblist[str] = sym + return sym + + +def parseline(str): + split = re.split(r"\s|([\[\]()])", str) + return [x for x in split if x and x != ""] + +def readline(lc, line): + res = [] + while line: + token = line.pop(0) + 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 == '[': res.append(readline(lc,line)) + elif token == ']': return res + else: res.append(intern(lc, token)) + return res + + +def setup_cmd(lc, str): + stopsignon(lc); lc.procstop=False + list = readline(lc, str) + lc.step = start_eval(lc, list) + +def start_eval(lc, list): + icall(lc, evline, list); yield True + yield False + +def evline(lc, list): + oldiline = lc.iline + lc.iline = list[:] + lc.arglist = None + while lc.iline: + token = lc.iline[0] + if token==lc.symopar: token=lc.iline[1] + icall(lc, eval); yield True + if lc.procstop: break + if lc.iresult==None: continue + raise logoerror("You don't say what to do with %s" % token) + lc.iline = oldiline + ireturn(lc); yield True + +def eval(lc, infixarg=False): + token = lc.iline.pop(0) + if type(token) == lc.symtype: + icall(lc, evalsym, token); yield True + res = lc.iresult + else: res = token + if not infixarg: + while infixnext(lc): + icall(lc, evalinfix, res); yield True + res = lc.iresult + ireturn(lc, res); yield True + +def evalsym(lc, token): + undefined_check(lc, token) + oldcfun, oldarglist = lc.cfun, lc.arglist + lc.cfun, lc.arglist = token, [] + for i in range(token.nargs): + no_args_check(lc) + icall(lc, eval); yield True + lc.arglist.append(lc.iresult) + if lc.cfun.rprim: + if type(lc.cfun.fcn)==lc.listtype: icall(lc, ufuncall, cfun.fcn); yield True + else: icall(lc, lc.cfun.fcn, *lc.arglist); yield True + result = None + else: result = lc.cfun.fcn(lc, *lc.arglist) + lc.cfun, lc.arglist = oldcfun, oldarglist + if lc.arglist!=None and result==None: + raise logoerror("%s didn't output to %s" % (oldcfun.name, lc.cfun.name)) + ireturn(lc, result); yield True + +def evalinfix(lc, firstarg): + token = lc.iline.pop(0) + oldcfun, oldarglist = lc.cfun, lc.arglist + lc.cfun, lc.arglist = token, [firstarg] + no_args_check(lc) + icall(lc, eval,True); yield True + lc.arglist.append(lc.iresult) + result = lc.cfun.fcn(lc,*lc.arglist) + lc.cfun, lc.arglist = oldcfun, oldarglist + ireturn (lc,result); yield True + +def infixnext(lc): + if len(lc.iline)==0: return False + if type(lc.iline[0])!=lc.symtype: return False + return lc.iline[0].name in ['+', '-', '*', '/','%','and','or'] + +def undefined_check(lc, token): + if token.fcn != None: return False + raise logoerror("I don't know how to %s" % token.name) + + +def no_args_check(lc): + if lc.iline and lc.iline[0]!=lc.symnothing : return + raise logoerror("Not enough inputs to %s" % lc.cfun.name) + +def prim_wait(lc,time): + setlayer(lc.tw.turtle.spr,630) + endtime = millis()+an_int(lc,time)*100 + while millis()<endtime: + yield True + setlayer(lc.tw.turtle.spr,100) + ireturn(lc); yield True + +def prim_repeat(lc, num, list): + num = an_int(lc, num) + for i in range(num): + icall(lc, evline, list[:]); yield True + if lc.procstop: break + ireturn(lc); yield True + +def prim_forever(lc, list): + while True: + icall(lc,evline, list[:]); yield True + if lc.procstop: break + ireturn(lc); yield True + +def prim_if(lc, bool, list): + if bool: icall(lc, evline, list[:]); yield True + ireturn(lc); yield True + +def prim_ifelse(lc, bool, list1,list2): + if bool: ijmp(lc, evline, list1[:]); yield True + else: ijmp(lc, evline, list2[:]); yield True + +def prim_opar(lc,val): + lc.iline.pop(0) + return val + +def prim_define(name, body): + if type(name) != symtype: name = intern(name) + name.nargs, name.fcn = 0, body + name.rprim = True + +def prim_stack1(lc): + if lc.stacks['stack1']==None: raise logoerror("stack1 undefined") + icall(lc, evline, lc.stacks['stack1'][:]); yield True + lc.procstop = False + ireturn(lc); yield True + +def prim_stack2(lc): + if lc.stacks['stack2']==None: raise logoerror("stack2 undefined") + icall(lc, evline, lc.stacks['stack2'][:]); yield True + lc.procstop = False + ireturn(lc); yield True + +def prim_stopstack(lc): + lc.procstop = True + +def ufuncall(body): + ijmp(evline, body); yield True + +def an_int(lc, n): + try: return int(n) + except: raise logoerror("%s doesn't like %s as input" % (lc.cfun.name, str(n))) + +def a_float(n): + try: return int(n) + except: raise logoerror("%s doesn't like %s as input" % (cfun.name, str(n))) + +def defprim(lc, name, args, fcn, rprim=False): + sym = intern(lc, name) + sym.nargs, sym.fcn = args,fcn + sym.rprim = rprim + +def lcNew(tw): + lc = taLogo() + lc.tw = tw + lc.oblist = {} + + defprim(lc,'print', 1, lambda lc,x: showlabel(lc,int(float(x)*10)/10.)) +# defprim(lc,'print', 1, lambda lc,x: tyo(int(float(x)*10)/10.)) + + defprim(lc,'+', None, lambda lc,x,y:x+y) + defprim(lc,'-', None, lambda lc,x,y:x-y) + defprim(lc,'*', None, lambda lc,x,y:x*y) + defprim(lc,'/', None, lambda lc,x,y:x/y) + defprim(lc,'random', 2, lambda lc,x,y: int(random.uniform(x,y))) + defprim(lc,'greater?', 2, lambda lc,x,y: float(x)>float(y)) + defprim(lc,'less?', 2, lambda lc,x,y: float(x)<float(y)) + defprim(lc,'equal?', 2, lambda lc,x,y: float(x)==float(y)) + defprim(lc,'and', None, lambda lc,x,y:x&y) + defprim(lc,'or', None, lambda lc,x,y:x|y) + defprim(lc,'not', 1, lambda lc,x:not x) + defprim(lc,'%', None, lambda lc,x,y:x%y) + + defprim(lc,'clean', 0, lambda lc: clearscreen(lc.tw.turtle)) + defprim(lc,'forward', 1, lambda lc, x: forward(lc.tw.turtle, x)) + defprim(lc,'back', 1, lambda lc,x: forward(lc.tw.turtle,-x)) + defprim(lc,'seth', 1, lambda lc, x: seth(lc.tw.turtle, x)) + defprim(lc,'right', 1, lambda lc, x: right(lc.tw.turtle, x)) + defprim(lc,'left', 1, lambda lc,x: right(lc.tw.turtle,-x)) + defprim(lc,'heading', 0, lambda lc: lc.tw.turtle.heading) + defprim(lc,'setxy', 2, lambda lc, x, y: setxy(lc.tw.turtle, x, y)) + defprim(lc,'arc', 2, lambda lc, x, y: arc(lc.tw.turtle, x, y)) + defprim(lc,'xcor', 0, lambda lc: lc.tw.turtle.xcor) + defprim(lc,'ycor', 0, lambda lc: lc.tw.turtle.ycor) + + defprim(lc,'pendown', 0, lambda lc: setpen(lc.tw.turtle, True)) + defprim(lc,'penup', 0, lambda lc: setpen(lc.tw.turtle, False)) + defprim(lc,'(', 1, lambda lc, x: prim_opar(lc,x)) + defprim(lc,'setcolor', 1, lambda lc, x: setcolor(lc.tw.turtle, x)) + defprim(lc,'setshade', 1, lambda lc, x: setshade(lc.tw.turtle, x)) + defprim(lc,'setpensize', 1, lambda lc, x: setpensize(lc.tw.turtle, x)) + defprim(lc,'fillscreen', 2, lambda lc, x, y: fillscreen(lc.tw.turtle, x, y)) + defprim(lc,'color', 0, lambda lc: lc.tw.turtle.color) + defprim(lc,'shade', 0, lambda lc: lc.tw.turtle.shade) + defprim(lc,'pensize', 0, lambda lc: lc.tw.turtle.pensize) + + defprim(lc,'wait', 1, prim_wait, True) + defprim(lc,'repeat', 2, prim_repeat, True) + defprim(lc,'forever', 1, prim_forever, True) + defprim(lc,'if', 2, prim_if, True) + defprim(lc,'ifelse', 3, prim_ifelse, True) + defprim(lc,'stopstack', 0, prim_stopstack) + + defprim(lc,'stack1', 0, prim_stack1, True) + defprim(lc,'stack2', 0, prim_stack2, True) + defprim(lc,'box1', 0, lambda lc: lc.boxes['box1']) + defprim(lc,'box2', 0, lambda lc: lc.boxes['box2']) + defprim(lc,'storeinbox1', 1, lambda lc,x: setbox(lc, 'box1',x)) + defprim(lc,'storeinbox2', 1, lambda lc,x: setbox(lc, 'box2',x)) + + defprim(lc,'define', 2, prim_define) + defprim(lc,'nop', 0, lambda lc: None) + defprim(lc,'start', 0, lambda: None) + + lc.symtype = type(intern(lc, 'print')) + lc.numtytpe = type(0.) + lc.listtype = type([]) + lc.symnothing = intern(lc, '%nothing%') + lc.symopar = intern(lc, '(') + + lc.istack = [] + lc.stacks = {} + lc.boxes = {'box1': 0, 'box2': 0} + + lc.iline, lc.cfun, lc.arglist, lc.ufun = None, None, None,None + + lc.stopsign = tw.toolsprs['stopit'] + + return lc + +def doevalstep(lc): + starttime = millis() + try: + while (millis()-starttime)<120: + if not lc.step.next(): stopsignoff(lc); return False + except logoerror, e: showlabel(lc, str(e)[1:-1]); stopsignoff(lc); return False + return True + +def icall(lc, fcn, *args): + lc.istack.append(lc.step) + lc.step = fcn(lc, *(args)) + +def ireturn(lc, res=None): + lc.step = lc.istack.pop() + lc.iresult = res + +def ijmp(lc, fcn, *args): + lc.step = fcn(lc,*(args)) + +def showlabel(lc,l): + setlabel(lc.tw.status_spr,l) + setlayer(lc.tw.status_spr,710); + +def stopsignon(lc): + setshape(lc.stopsign, lc.stopsign.onshape) + setlayer(lc.tw.turtle.spr,100) + +def stopsignoff(lc): + setshape(lc.stopsign, lc.stopsign.offshape) + setlayer(lc.tw.turtle.spr,630) + +def stop_logo(tw): tw.lc.step = just_stop() +def just_stop(): yield False + +def setbox(lc, name,val): lc.boxes[name]=val +def tyo(n): print n +def millis(): return int(clock()*1000) + diff --git a/talogo.pyc b/talogo.pyc Binary files differnew file mode 100755 index 0000000..40f12ae --- /dev/null +++ b/talogo.pyc diff --git a/taproject.py b/taproject.py new file mode 100755 index 0000000..bd8d86c --- /dev/null +++ b/taproject.py @@ -0,0 +1,137 @@ +import pygtk +pygtk.require('2.0') +import gtk +import pickle +import os.path + +from tasprites import * +from taturtle import * +from talogo import stop_logo + +def new_project(tw): + stop_logo(tw) + for b in blocks(tw): hide(b) + setlayer(tw.turtle.canvas, 600) + setshape(tw.toolsprs['hideshow'], tw.toolsprs['hideshow'].offshape) + clearscreen(tw.turtle) + tw.save_file_name = None + +def load_file(tw): + fname = get_load_name(tw) + if fname==None: return + if fname[-3:]=='.ta': fname=fname[0:-3] + load_files(tw,fname+'.ta', fname+'.png') + tw.save_file_name = os.path.basename(fname) + +def load_files(tw,ta_file, png_file=''): + f = open(ta_file, "r") + data = pickle.load(f) + f.close() + new_project(tw) + read_data(tw,data) + try: + load_pict(tw,png_file) + except: + print "load_files: picture didn't load" + pass + inval(tw.turtle.canvas) + +def get_load_name(tw): + dialog = gtk.FileChooserDialog("Load...", None, + gtk.FILE_CHOOSER_ACTION_OPEN, + (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN, gtk.RESPONSE_OK)) + dialog.set_default_response(gtk.RESPONSE_OK) + return do_dialog(tw,dialog) + +def read_data(tw,data): + blocks = [] + for b in data: + if b[1]=='turtle': load_turtle(tw,b) + else: spr = load_spr(tw,b); blocks.append(spr) + for i in range(len(blocks)): + cons=[] + for c in data[i][4]: + if c==None: cons.append(None) + else: cons.append(blocks[c]) + blocks[i].connections = cons + +def load_spr(tw,b): + btype, label = b[1],None + if type(btype)==type((1,2)): btype, label = btype + proto = tw.protodict[btype] + spr = sprNew(tw,b[2]+tw.turtle.canvas.x,b[3]+tw.turtle.canvas.y, proto.image) + spr.type = 'block' + spr.proto = proto + if label!=None: spr.label=label + setlayer(spr,650) + return spr + +def load_turtle(tw,b): + id, name, xcor, ycor, heading, color, shade, pensize = b + setxy(tw.turtle, xcor, ycor) + seth(tw.turtle, heading) + setcolor(tw.turtle, color) + setshade(tw.turtle, shade) + setpensize(tw.turtle, pensize) + +def load_pict(tw,fname): + pict = gtk.gdk.pixbuf_new_from_file(fname) + tw.turtle.canvas.image.draw_pixbuf(tw.turtle.gc, pict, 0, 0, 0, 0) + +def save_file(tw): + fname = get_save_name(tw) + if fname==None: return + if fname[-3:]=='.ta': fname=fname[0:-3] + save_data(tw,fname+".ta") + save_pict(tw,fname+".png") + tw.save_file_name = os.path.basename(fname) + +def get_save_name(tw): + dialog = gtk.FileChooserDialog("Save..", None, + gtk.FILE_CHOOSER_ACTION_SAVE, + (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE, gtk.RESPONSE_OK)) + dialog.set_default_response(gtk.RESPONSE_OK) + if tw.save_file_name!=None: dialog.set_current_name(tw.save_file_name+'.ta') + return do_dialog(tw,dialog) + +def save_data(tw,fname): + f = file(fname, "w") + bs = blocks(tw) + data = [] + for i in range(len(bs)): bs[i].id=i + for b in bs: + name = b.proto.name + if name=='number': name=(name,b.label) + connections = [get_id(x) for x in b.connections] + data.append((b.id,name,b.x-tw.turtle.canvas.x,b.y-tw.turtle.canvas.y,connections)) + data.append((-1,'turtle', + tw.turtle.xcor,tw.turtle.ycor,tw.turtle.heading, + tw.turtle.color,tw.turtle.shade,tw.turtle.pensize)) + pickle.dump(data,f) + f.close() + +def save_pict(tw,fname): + tc = tw.turtle.canvas + pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, tc.width, tc.height) + pixbuf.get_from_drawable(tc.image, tc.image.get_colormap(), 0, 0, 0, 0, tc.width, tc.height) + pixbuf.save(fname, 'png') + +def get_id(x): + if x==None: return None + return x.id + +def do_dialog(tw,dialog): + result = None + filter = gtk.FileFilter() + filter.add_pattern("*.ta") + filter.set_name("Turtle Art") + dialog.add_filter(filter) + dialog.set_current_folder(tw.load_save_folder) + response = dialog.run() + if response == gtk.RESPONSE_OK: + result = dialog.get_filename() + tw.load_save_folder = dialog.get_current_folder() + dialog.destroy() + return result + +def blocks(tw): return [spr for spr in tw.sprites if spr.type == 'block'] diff --git a/taproject.pyc b/taproject.pyc Binary files differnew file mode 100755 index 0000000..a4b1f40 --- /dev/null +++ b/taproject.pyc diff --git a/turtlesetup.py b/tasetup.py index 8106820..c06003c 100755 --- a/turtlesetup.py +++ b/tasetup.py @@ -3,12 +3,12 @@ pygtk.require('2.0') import gtk import gobject import os -#import os.path +class taProto: pass -from sprites import * +from tasprites import * selectors = ( - ('turtle', 37, + ('turtle', 55, (('clean','clean','noarg'), ('forward','forward','onearg',100), ('back','back','onearg',100), @@ -20,7 +20,7 @@ selectors = ( ('xcor','xcor','num'), ('ycor','ycor','num'), ('heading','heading','num'))), - ('pen', 30, + ('pen', 45, (('penup','penup','noarg'), ('pendown','pendown','noarg'), ('setpensize','setpensize','1arg',5), @@ -30,7 +30,7 @@ selectors = ( ('pensize','pensize','num'), ('color','color','num'), ('shade','shade','num'))), - ('numbers', 55, + ('numbers', 77, (('number','','num'), ('plus','+','ari'), ('minus','-','ari'), @@ -43,9 +43,8 @@ selectors = ( ('equal','equal?','comp'), ('and','and','and'), ('or','or','and'), - ('not','not','not'), - ('print','print','onearg'))), - ('flow', 30, + ('not','not','not'), ('print','print','onearg'))), + ('flow', 45, (('wait','wait','onearg',10), ('forever','forever','forever'), ('repeat','repeat','repeat',4), @@ -54,7 +53,7 @@ selectors = ( ('ifelse','ifelse','ifelse'), ('hspace','nop','hspace'), ('vspace','nop','vspace'))), - ('myblocks', 46, + ('myblocks', 69, (('hat1','nop','start'), ('stack1','stack1','noarg'), ('hat2','nop','start'), @@ -65,9 +64,7 @@ selectors = ( ('box2','box2','num')))) toolbaritems = ( -# ('new',0,20),('open',70,20), ('save',70,20), - ('hideshow',700, 725),('eraser',54,725), ('stopit',54,725)) -# ('hideshow',200, 2),('eraser',54,3), ('stopit',54,2)) + ('hideshow',1050),('eraser',50), ('stopit',50)) dockdetails = { 'noarg': (('flow',True,37,5),('flow',False,37,44)), @@ -91,78 +88,71 @@ dockdetails = { 'start': (('start',True,50,0),('flow',False,49,55)) } -protodict = {} -toolsprs = {} -base_path = None -class BlockProto: - def __init__(self,name): - self.name = name - - -def setup_selectors(path): - global base_path - base_path = path +def setup_selectors(tw): + tw.protodict = {} y = 25 - categories = [] + tw.selbuttons = [] for s in selectors: name,dy,blockdescriptions = s - cat = setup_selector(name,y, blockdescriptions) - y += dy*3/2 - categories.append(cat) - category_spr = Sprite(0, 0, categories[0].group) - category_spr.type = 'category' - category_spr.setlayer(660) - return category_spr, categories, categories[0] + cat = setup_selector(tw,name,y, blockdescriptions) + y += dy + tw.selbuttons.append(cat) + tw.category_spr = sprNew(tw,0, 0, tw.selbuttons[0].group) + tw.category_spr.type = 'category' + setlayer(tw.category_spr,660) + tw.select_mask = sprNew(tw,100,100,load_image(tw.path, '', 'masknumber')) + tw.select_mask.type = 'selectmask' + tw.hidden_palette_icon = load_image(tw.path, 'toolbar','blocks-') + tw.status_spr = sprNew(tw,0,743,load_image(tw.path, '', 'status'),True) + tw.status_spr.type = 'status' + setlayer(tw.status_spr,400) -def setup_selector(name,y,blockdescriptions): - offshape = gtk.gdk.pixbuf_new_from_file(os.path.join(base_path, 'palette',name+'off.gif')) - onshape = gtk.gdk.pixbuf_new_from_file(os.path.join(base_path, 'palette',name+'on.gif')) - who = Sprite(140,y,offshape) - who.setlayer(800) +def setup_selector(tw,name,y,blockdescriptions): + offshape = load_image(tw.path,'palette',name+'off') + onshape = load_image(tw.path,'palette',name+'on') + who = sprNew(tw,140,y,offshape) + setlayer(who,800) who.offshape = offshape who.onshape = onshape - who.group = gtk.gdk.pixbuf_new_from_file(os.path.join(base_path, name,name+'group.gif')) - maskname = os.path.join(base_path, name,name+'mask.gif') - if os.access(maskname, os.F_OK): - who.mask = gtk.gdk.pixbuf_new_from_file(maskname) - else: who.mask = None + who.group = load_image(tw.path, name,name+'group') + who.mask = load_image(tw.path, name,name+'mask') who.type = 'selbutton' protos = [] for b in blockdescriptions: bname,primname,docktype = b[0:3] - image = gtk.gdk.pixbuf_new_from_file(os.path.join(base_path, name, bname+'.gif')) - proto = BlockProto(bname) + image = load_image(tw.path, name, bname) + proto = taProto() + proto.name = bname proto.image = image proto.primname=primname proto.defaults=b[3:] if docktype in dockdetails: proto.docks=dockdetails[docktype] else: proto.docks = docktype - protodict[bname] = proto + tw.protodict[bname] = proto protos.append(proto) who.blockprotos = protos return who -def setup_toolbar(): - x,y = 330,0 +def setup_toolbar(tw): + tw.toolsprs = {} + x,y = 0,20 for s in toolbaritems: - name,dx,dy= s + name,dx= s x += dx - setup_tool(x,y + dy,name) + tw.toolsprs[name]=setup_tool(tw,x,y,name) return -def setup_tool(x,y,name): - offshape = gtk.gdk.pixbuf_new_from_file(os.path.join(base_path, 'toolbar',name+'off.gif')) - onshape = gtk.gdk.pixbuf_new_from_file(os.path.join(base_path, 'toolbar',name+'on.gif')) - who = Sprite(x,y,offshape) - who.setlayer(800) +def setup_tool(tw,x,y,name): + offshape = load_image(tw.path, 'toolbar',name+'off') + onshape = load_image(tw.path, 'toolbar',name+'on') + who = sprNew(tw,x,y,offshape) + setlayer(who,800) who.offshape = offshape who.onshape = onshape who.type = 'tool' who.blocktype = name - toolsprs[name] = who - -def blockproto(name): return protodict[name] - -def toolsprite(name): return toolsprs[name] + return who +def load_image(path, dir, file): + return gtk.gdk.pixbuf_new_from_file(os.path.join(path,dir,file+'.gif')) diff --git a/tasetup.pyc b/tasetup.pyc Binary files differnew file mode 100755 index 0000000..c5a3c71 --- /dev/null +++ b/tasetup.pyc diff --git a/tasprites.py b/tasprites.py new file mode 100755 index 0000000..a10612c --- /dev/null +++ b/tasprites.py @@ -0,0 +1,112 @@ +import pygtk +pygtk.require('2.0') +import gtk +import gobject +import pango +class taSprite: pass + +def findsprite(tw,pos): + list = tw.sprites[:] + list.reverse() + for s in list: + if hit(s,pos): return s + return None + +def redrawsprites(tw): + for s in tw.sprites: draw(s) + + +def sprNew(tw,x,y,image,altlabel=False): + spr = taSprite() + spr.tw, spr.x, spr.y = tw,x,y + setimage(spr,image) + spr.label = None + if altlabel: spr.draw_label = draw_label2 + else: spr.draw_label = draw_label1 + return spr + +def setimage(spr,image): + spr.image = image + if isinstance(image,gtk.gdk.Pixbuf): + spr.width = image.get_width() + spr.height = image.get_height() + else: spr.width,spr.height=image.get_size() + + +def move(spr,pos): + inval(spr) + spr.x,spr.y = pos + inval(spr) + +def setshape(spr,image): + inval(spr) + setimage(spr,image) + inval(spr) + +def setlayer(spr, layer): + sprites = spr.tw.sprites + if spr in sprites: sprites.remove(spr) + spr.layer = layer + for i in range(len(sprites)): + if layer < sprites[i].layer: sprites.insert(i, spr); inval(spr); return + sprites.append(spr) + inval(spr) + +def hide(spr): + if spr not in spr.tw.sprites: return + inval(spr) + spr.tw.sprites.remove(spr) + +def setlabel(spr,label): + spr.label = label + inval(spr) + +def inval(spr): + spr.tw.area.invalidate_rect(gtk.gdk.Rectangle(spr.x,spr.y,spr.width,spr.height), False) + +def draw(spr): + if isinstance(spr.image,gtk.gdk.Pixbuf): + spr.tw.area.draw_pixbuf(spr.tw.gc, spr.image, 0, 0, spr.x, spr.y) + else: spr.tw.area.draw_drawable(spr.tw.gc,spr.image,0,0,spr.x,spr.y,-1,-1) + if spr.label!=None: spr.draw_label(spr,spr.label) + +def hit(spr,pos): + x,y = pos + if x<spr.x: return False + if x>spr.x+spr.width: return False + if y<spr.y: return False + if y>spr.y+spr.height: return False + if isinstance(spr.image,gtk.gdk.Pixmap): return True + dx,dy = x-spr.x, y-spr.y + return ord(spr.image.get_pixels()[(dy*spr.width+dx)*4+3]) == 255 + +def draw_label1(spr, label): + fd = pango.FontDescription('Sans') + fd.set_size(7*pango.SCALE) + pl = spr.tw.window.create_pango_layout(str(label)) + pl.set_font_description(fd) + swidth = pl.get_size()[0]/pango.SCALE + sheight = pl.get_size()[1]/pango.SCALE + centerx = spr.x+spr.width/2 + centery = spr.y+spr.height/2 + spr.tw.gc.set_foreground(spr.tw.textcolor) + spr.tw.area.draw_layout(spr.tw.gc,centerx-swidth/2,centery-sheight/2,pl) + +def draw_label2(spr, label): + fd = pango.FontDescription('Sans') + fd.set_size(9*pango.SCALE) + pl = spr.tw.window.create_pango_layout(str(label)) + pl.set_font_description(fd) + sheight = pl.get_size()[1]/pango.SCALE + centery = spr.y+spr.height/2 + spr.tw.gc.set_foreground(spr.tw.textcolor) + spr.tw.area.draw_layout(spr.tw.gc,spr.x+50,centery-sheight/2,pl) + + +def getpixel(image,x,y): + array = image.get_pixels() + offset = (y*image.get_width()+x)*4 + r,g,b,a = ord(array[offset]),ord(array[offset+1]),ord(array[offset+2]),ord(array[offset+3]) + return (a<<24)+(b<<16)+(g<<8)+r + + diff --git a/tasprites.pyc b/tasprites.pyc Binary files differnew file mode 100755 index 0000000..02a97eb --- /dev/null +++ b/tasprites.pyc diff --git a/taturtle.py b/taturtle.py new file mode 100755 index 0000000..a74940a --- /dev/null +++ b/taturtle.py @@ -0,0 +1,174 @@ +import gtk +from math import sin,cos,pi +class taTurtle: pass + +from tasprites import * +from tasetup import load_image + +colors = {} +DEGTOR = 2*pi/360 + +color_table = ( + 0xFF0000,0xFF0D00,0xFF1A00,0xFF2600,0xFF3300,0xFF4000,0xFF4D00,0xFF5900,0xFF6600,0xFF7300, + 0xFF8000,0xFF8C00,0xFF9900,0xFFA600,0xFFB300,0xFFBF00,0xFFCC00,0xFFD900,0xFFE600,0xFFF200, + 0xFFFF00,0xE6FF00,0xCCFF00,0xB3FF00,0x99FF00,0x80FF00,0x66FF00,0x4DFF00,0x33FF00,0x1AFF00, + 0x00FF00,0x00FF0D,0x00FF1A,0x00FF26,0x00FF33,0x00FF40,0x00FF4D,0x00FF59,0x00FF66,0x00FF73, + 0x00FF80,0x00FF8C,0x00FF99,0x00FFA6,0x00FFB3,0x00FFBF,0x00FFCC,0x00FFD9,0x00FFE6,0x00FFF2, + 0x00FFFF,0x00F2FF,0x00E6FF,0x00D9FF,0x00CCFF,0x00BFFF,0x00B3FF,0x00A6FF,0x0099FF,0x008CFF, + 0x0080FF,0x0073FF,0x0066FF,0x0059FF,0x004DFF,0x0040FF,0x0033FF,0x0026FF,0x001AFF,0x000DFF, + 0x0000FF,0x0D00FF,0x1A00FF,0x2600FF,0x3300FF,0x4000FF,0x4D00FF,0x5900FF,0x6600FF,0x7300FF, + 0x8000FF,0x8C00FF,0x9900FF,0xA600FF,0xB300FF,0xBF00FF,0xCC00FF,0xD900FF,0xE600FF,0xF200FF, + 0xFF00FF,0xFF00E6,0xFF00CC,0xFF00B3,0xFF0099,0xFF0080,0xFF0066,0xFF004D,0xFF0033,0xFF001A) + +def tNew(tw,w,h): + t = taTurtle() + t.tw, t.width, t.height = tw, w, h + t.canvas = sprNew(tw,0,0,gtk.gdk.Pixmap(tw.area,w,h,-1)) + t.canvas.type = 'canvas' + setlayer(t.canvas,600) + t.shapelist = [load_image(tw.path, 'shapes','t'+str(i)) for i in range(36)] + t.spr = sprNew(tw,100,100,t.shapelist[0]) + t.spr.type = 'turtle' + setlayer(t.spr, 630) + t.gc = t.canvas.image.new_gc() + t.shade = 0 + clearscreen(t) + return t + +def clearscreen(t): + t.xcor, t.ycor, t.heading = 0,0,0 + rect = gtk.gdk.Rectangle(0,0,t.width,t.height) + t.gc.set_foreground(t.tw.bgcolor) + t.canvas.image.draw_rectangle(t.gc, True, *rect) + invalt(t,0,0,t.width,t.height) + setpensize(t,5) + setcolor(t,0) + setshade(t,50) + t.pendown = True + move_turtle(t) + turn_turtle(t) + return None + +def forward(t, n): + t.gc.set_foreground(t.fgcolor) + oldx, oldy = t.xcor, t.ycor + t.xcor += n*sin(t.heading*DEGTOR) + t.ycor += n*cos(t.heading*DEGTOR) + if t.pendown: draw_line(t,oldx,oldy,t.xcor,t.ycor) + move_turtle(t) + return None + +def seth(t,n): + t.heading=n + t.heading%=360 + turn_turtle(t) + return None + +def right(t,n): + t.heading+=n + t.heading%=360 + turn_turtle(t) + return None + +def arc(t,a,r): + t.gc.set_foreground(t.fgcolor) + if a<0: larc(t,-a,r) + else: rarc(t,a,r) + move_turtle(t) + turn_turtle(t) + +def rarc(t,a,r): + if r<0: r=-r; a=-a + cx = t.xcor+r*cos(t.heading*DEGTOR) + cy = t.ycor-r*sin(t.heading*DEGTOR) + x,y,w,h=t.width/2+int(cx-r),t.height/2-int(cy+r),int(2*r),int(2*r) + t.canvas.image.draw_arc(t.gc,False,x,y,w,h,int(180-t.heading-a)*64,int(a)*64) + invalt(t,x-t.pensize/2-3,y-t.pensize/2-3,w+t.pensize+6,h+t.pensize+6) + right(t,a) + t.xcor=cx-r*cos(t.heading*DEGTOR) + t.ycor=cy+r*sin(t.heading*DEGTOR) + +def larc(t,a,r): + if r<0: r=-r; a=-a + cx = t.xcor-r*cos(t.heading*DEGTOR) + cy = t.ycor+r*sin(t.heading*DEGTOR) + x,y,w,h=t.width/2+int(cx-r),t.height/2-int(cy+r),int(2*r),int(2*r) + t.canvas.image.draw_arc(t.gc,False,x,y,w,h,int(360-t.heading)*64,int(a)*64) + invalt(t,x-t.pensize/2-3,y-t.pensize/2-3,w+t.pensize+6,h+t.pensize+6) + right(t,-a) + t.xcor=cx+r*cos(t.heading*DEGTOR) + t.ycor=cy-r*sin(t.heading*DEGTOR) + +def setxy(t,x,y): + t.xcor,t.ycor = x,y + move_turtle(t) + +def setpensize(t,ps): + t.pensize = ps + t.gc.set_line_attributes(int(t.pensize),gtk.gdk.LINE_SOLID,gtk.gdk.CAP_ROUND,gtk.gdk.JOIN_MITER) + return None + +def setcolor(t,c): + t.color = c + set_fgcolor(t) + return None + +def setshade(t,s): + t.shade = s + set_fgcolor(t) + return None + +def fillscreen(t,c,s): + oldc, olds = t.color,t.shade + setcolor(t,c); setshade(t,s) + rect = gtk.gdk.Rectangle(0,0,t.width,t.height) + t.gc.set_foreground(t.fgcolor) + t.canvas.image.draw_rectangle(t.gc, True, *rect) + invalt(t,0,0,t.width,t.height) + setcolor(t,oldc); setshade(t,olds) + return None + +def set_fgcolor(t): + sh = (wrap100(t.shade)-50)/50.0 + rgb = color_table[wrap100(t.color)] + r,g,b = (rgb>>8)&0xff00,rgb&0xff00,(rgb<<8)&0xff00 + r,g,b = calc_shade(r,sh),calc_shade(g,sh),calc_shade(b,sh) + t.fgcolor = t.tw.cm.alloc_color(r,g,b) + +def wrap100(n): + n = int(n) + n %= 200 + if n>99: n=199-n + return n + +def calc_shade(c,s): + if s<0: return int(c*(1+s*.8)) + return int(c+(65536-c)*s*.9) + +def setpen(t,bool): + t.pendown = bool + +def draw_line(t,x1,y1,x2,y2): + x1,y1 = t.width/2+int(x1), t.height/2-int(y1) + x2,y2 = t.width/2+int(x2), t.height/2-int(y2) + if x1<x2: minx,maxx=x1,x2 + else: minx,maxx=x2,x1 + if y1<y2: miny,maxy=y1,y2 + else: miny,maxy=y2,y1 + w,h=maxx-minx,maxy-miny + t.canvas.image.draw_line(t.gc,x1,y1,x2,y2) + invalt(t,minx-t.pensize/2-3,miny-t.pensize/2-3,w+t.pensize+6,h+t.pensize+6) + +def turn_turtle(t): + setshape(t.spr, t.shapelist[(int(t.heading+5)%360)/10]) + +def move_turtle(t): + x,y = t.width/2+int(t.xcor), t.height/2-int(t.ycor) + move(t.spr, (t.canvas.x+x-30,t.canvas.y+y-30)) + invalt(t,x-30,y-30,60,60) + +def invalt(t,x,y,w,h): + rect = gtk.gdk.Rectangle(int(x+t.canvas.x),int(y+t.canvas.y),int(w),int(h)) + t.tw.area.invalidate_rect(rect, False) + + diff --git a/taturtle.pyc b/taturtle.pyc Binary files differnew file mode 100755 index 0000000..912dad6 --- /dev/null +++ b/taturtle.pyc diff --git a/tawindow.py b/tawindow.py new file mode 100755 index 0000000..0ab026e --- /dev/null +++ b/tawindow.py @@ -0,0 +1,360 @@ +import pygtk +pygtk.require('2.0') +import gtk +import gobject +import os +import os.path +class taWindow: pass + +WIDTH=1200 +HEIGHT=780 + +from math import atan2, pi +DEGTOR = 2*pi/360 + +from tasetup import * +from tasprites import * +from talogo import * +from taturtle import * +from taproject import * + +# +# Setup +# + +def twNew(win, path, parent=None): + tw = taWindow() + tw.window = win + tw.path=path + win.set_flags(gtk.CAN_FOCUS) + win.set_size_request(WIDTH, HEIGHT) + if parent is None: win.show_all() + else: parent.show_all() + win.add_events(gtk.gdk.BUTTON_PRESS_MASK) + win.add_events(gtk.gdk.BUTTON_RELEASE_MASK) + win.add_events(gtk.gdk.POINTER_MOTION_MASK) + win.add_events(gtk.gdk.KEY_PRESS_MASK) + win.connect("expose-event", expose_cb, tw) + win.connect("button-press-event", buttonpress_cb, tw) + win.connect("button-release-event", buttonrelease_cb, tw) + win.connect("motion-notify-event", move_cb, tw) + win.connect("key_press_event", keypress_cb, tw) + tw.area = win.window + tw.gc = tw.area.new_gc() + tw. cm = tw.gc.get_colormap() + tw.bgcolor = tw.cm.alloc_color('#fff8de') + tw.textcolor = tw.cm.alloc_color('black') + tw.sprites = [] + tw.selected_block = None + tw.draggroup = None + setup_selectors(tw) + setup_toolbar(tw) + select_category(tw, tw.selbuttons[0]) + tw.turtle = tNew(tw,WIDTH,HEIGHT) + tw.lc = lcNew(tw) + tw.load_save_folder = os.path.join(path,'samples') + tw.save_file_name = None + return tw + + +# +# Button Press +# + +def buttonpress_cb(win, event, tw): + win.grab_focus() + tw.block_operation = 'click' + if tw.selected_block!=None: unselect(tw) + setlayer(tw.status_spr,400) + pos = xy(event) + x,y = pos + spr = findsprite(tw,pos) + if spr==None: return True + if spr.type == 'selbutton': + select_category(tw,spr) + elif spr.type == 'tool': + tooldispatch(tw, spr) + elif spr.type == 'category': + block_selector_pressed(tw,x,y) + elif spr.type == 'block': + block_pressed(tw,event,x,y,spr) + elif spr.type == 'turtle': + turtle_pressed(tw,x,y) + return True + + +def block_selector_pressed(tw,x,y): + if tw.category_spr.image==tw.hidden_palette_icon: + for i in tw.selbuttons: setlayer(i,800) + select_category(tw,tw.selbuttons[0]) + else: + proto = get_proto_from_category(tw,x,y) + if proto==None: return + if proto!='hide': new_block_from_category(tw,proto,x,y) + else: + for i in tw.selbuttons: hide(i) + setshape(tw.category_spr, tw.hidden_palette_icon) + +def get_proto_from_category(tw,x,y): + dx,dy = x-tw.category_spr.x, y-tw.category_spr.y, + pixel = getpixel(tw.current_category.mask,dx,dy) + index = ((pixel%256)>>3)-1 + if index==0: return 'hide' + index-=1 + if index>len(tw.current_category.blockprotos): return None + return tw.current_category.blockprotos[index] + +def select_category(tw, spr): + if hasattr(tw, 'current_category'): + setshape(tw.current_category, tw.current_category.offshape) + setshape(spr, spr.onshape) + tw.current_category = spr + setshape(tw.category_spr,spr.group) + +def new_block_from_category(tw,proto,x,y): + tw.block_operation = 'new' + if proto == None: return True + newspr = sprNew(tw,x-20,y-20,proto.image) + setlayer(newspr,2000) + tw.dragpos = 20,20 + newspr.type = 'block' + newspr.proto = proto + if newspr.proto.name == 'number': newspr.label=100 + newspr.connections = [None]*len(proto.docks) + for i in range(len(proto.defaults)): + dock = proto.docks[i+1] + numproto = tw.protodict['number'] + numdock = numproto.docks[0] + nx,ny = newspr.x+dock[2]-numdock[2],newspr.y+dock[3]-numdock[3] + argspr = sprNew(tw,nx,ny,numproto.image) + argspr.type = 'block' + argspr.proto = numproto + argspr.label = str(proto.defaults[i]) + setlayer(argspr,2000) + argspr.connections = [newspr,None] + newspr.connections[i+1] = argspr + tw.draggroup = findgroup(newspr) + +def block_pressed(tw,event,x,y,spr): + if event.get_state()>k.gdk.CONTROL_MASK: + newspr = clone_stack(tw,x-spr.x-20,y-spr.y-20, spr) + tw.dragpos = x-newspr.x,y-newspr.y + tw.draggroup = findgroup(newspr) + else: + tw.dragpos = x-spr.x,y-spr.y + tw.draggroup = findgroup(spr) + for b in tw.draggroup: setlayer(b,2000) + disconnect(spr) + +def clone_stack(tw,dx,dy,spr): + newspr = sprNew(tw,spr.x+dx,spr.y+dy,spr.proto.image) + newspr.type = spr.type + newspr.proto = spr.proto + newspr.label = spr.label + newspr.connections = [None]*len(spr.proto.docks) + for i in range(1,len(spr.connections)): + if(spr.connections[i]==None): continue + clonearg=clone_stack(tw,dx,dy,spr.connections[i]) + newspr.connections[i]=clonearg + clonearg.connections[0]=newspr + setlayer(newspr,2000) + return newspr + +def turtle_pressed(tw,x,y): + dx,dy = x-tw.turtle.spr.x-30,y-tw.turtle.spr.y-30 + if dx*dx+dy*dy > 200: tw.dragpos = ('turn', tw.turtle.heading-atan2(dy,dx)/DEGTOR,0) + else: tw.dragpos = ('move', x-tw.turtle.spr.x,y-tw.turtle.spr.y) + tw.draggroup = [tw.turtle.spr] + + +# +# Mouse move +# + +def move_cb(win, event, tw): + if tw.draggroup == None: return True + tw.block_operation = 'move' + spr = tw.draggroup[0] + x,y = xy(event) + if spr.type=='block': + dragx, dragy = tw.dragpos + dx,dy = x-dragx-spr.x,y-dragy-spr.y + for b in tw.draggroup: + move(b,(b.x+dx, b.y+dy)) + elif spr.type=='turtle': + type,dragx,dragy = tw.dragpos + if type == 'move': + dx,dy = x-dragx-spr.x,y-dragy-spr.y + move(spr, (spr.x+dx, spr.y+dy)) + else: + dx,dy = x-spr.x-30,y-spr.y-30 + seth(tw.turtle, int(dragx+atan2(dy,dx)/DEGTOR+5)/10*10) + return True + + +# +# Button release +# + +def buttonrelease_cb(win, event, tw): + if tw.draggroup == None: return True + spr = tw.draggroup[0] + x,y = xy(event) + if spr.type == 'turtle': + tw.turtle.xcor = tw.turtle.spr.x-tw.turtle.canvas.x-tw.turtle.canvas.width/2+30 + tw.turtle.ycor = tw.turtle.canvas.height/2-tw.turtle.spr.y+tw.turtle.canvas.y-30 + move_turtle(tw.turtle) + tw.draggroup = None + return True + if tw.block_operation=='move' and hit(tw.category_spr, (x,y)): + for b in tw.draggroup: hide(b) + tw.draggroup = None + return True + snap_to_dock(tw) + for b in tw.draggroup: setlayer(b,650) + tw.draggroup = None + if tw.block_operation=='click': + if spr.proto.name=='number': + tw.selected_block = spr + move(tw.select_mask, (spr.x-6,spr.y-6)) + setlayer(tw.select_mask, 660) + tw.firstkey = True + else: run_stack(tw, spr) + return True + +def snap_to_dock(tw): + d=200 + me = tw.draggroup[0] + for mydockn in range(len(me.proto.docks)): + for you in blocks(tw): + if you in tw.draggroup: continue + for yourdockn in range(len(you.proto.docks)): + thisxy = dock_dx_dy(you,yourdockn,me,mydockn) + if magnitude(thisxy)>d: continue + d=magnitude(thisxy) + bestxy=thisxy + bestyou=you + bestyourdockn=yourdockn + bestmydockn=mydockn + if d<200: + for b in tw.draggroup: move(b,(b.x+bestxy[0],b.y+bestxy[1])) + blockindock=bestyou.connections[bestyourdockn] + if blockindock!=None: + for b in findgroup(blockindock): hide(b) + bestyou.connections[bestyourdockn]=me + me.connections[bestmydockn]=bestyou + +def dock_dx_dy(block1,dock1n,block2,dock2n): + dock1 = block1.proto.docks[dock1n] + dock2 = block2.proto.docks[dock2n] + d1type,d1dir,d1x,d1y=dock1[0:4] + d2type,d2dir,d2x,d2y=dock2[0:4] + if (d2type!='num') or (dock2n!=0): + if block1.connections[dock1n] != None: return (100,100) + if block2.connections[dock2n] != None: return (100,100) + if block1==block2: return (100,100) + if d1type!=d2type: return (100,100) + if d1dir==d2dir: return (100,100) + return (block1.x+d1x)-(block2.x+d2x),(block1.y+d1y)-(block2.y+d2y) + +def magnitude(pos): + x,y = pos + return x*x+y*y + + +# +# Repaint +# + +def expose_cb(win, event, tw): +# tw.gc.set_foreground(tw.bgcolor) +# tw.area.draw_rectangle(tw.gc, True, 0, 0, WIDTH, HEIGHT) + redrawsprites(tw) + return True + + +# +# Keyboard +# + +def keypress_cb(area, event,tw): + keyname = gtk.gdk.keyval_name(event.keyval) +# print keyname + if (event.get_state()>k.gdk.CONTROL_MASK): + if keyname=="n": new_project(tw) + if keyname=="o": load_file(tw) + if keyname=="s": save_file(tw) + if keyname=="k": tw.activity.clear_journal() + return True + if tw.selected_block==None: return False + keyname = gtk.gdk.keyval_name(event.keyval) + if keyname in ['minus', 'period']: keyname = {'minus': '-', 'period': '.'}[keyname] + if len(keyname)>1: return True + oldnum = tw.selected_block.label + if tw.firstkey: newnum = numcheck(keyname,'0') + else: newnum = oldnum+keyname + setlabel(tw.selected_block, numcheck(newnum,oldnum)) + tw.firstkey = False + return True + +def numcheck(new, old): + if new in ['-', '.', '-.']: return new + if new=='.': return '0.' + try: float(new); return new + except ValueError,e : return old + +def unselect(tw): + if tw.selected_block.label in ['-', '.', '-.']: select_block.setlabel('0') + hide(tw.select_mask) + tw.selected_block = None + + +# +# Block utilities +# + +def disconnect(b): + if b.connections[0]==None: return + b2=b.connections[0] + b2.connections[b2.connections.index(b)] = None + b.connections[0] = None + +def run_stack(tw,spr): + top = find_top_block(spr) + run_blocks(tw.lc, top, blocks(tw)) + gobject.idle_add(doevalstep, tw.lc) + +def findgroup(b): + group=[b] + for b2 in b.connections[1:]: + if b2!=None: group.extend(findgroup(b2)) + return group + +def find_top_block(spr): + while spr.connections[0]!=None: spr=spr.connections[0] + return spr + + +def tooldispatch(tw, spr): + if spr.blocktype == 'hideshow': hideshow_blocks(tw,spr) + elif spr.blocktype == 'eraser': runtool(tw, spr, clearscreen, tw.turtle) + elif spr.blocktype == 'stopit': stop_logo(tw) + +def runtool(tw, spr, cmd, *args): + setshape(spr,spr.onshape) + cmd(*(args)) + gobject.timeout_add(250,setshape,spr,spr.offshape) + +def hideshow_blocks(tw,spr): + if spr.image==spr.offshape: + for b in blocks(tw): setlayer(b,100) + setshape(spr,spr.onshape) + else: + for b in blocks(tw): setlayer(b,650) + setshape(spr,spr.offshape) + inval(tw.turtle.canvas) + + +def blocks(tw): return [spr for spr in tw.sprites if spr.type == 'block'] +def xy(event): return map(int, event.get_coords()) + diff --git a/tawindow.pyc b/tawindow.pyc Binary files differnew file mode 100755 index 0000000..b18d858 --- /dev/null +++ b/tawindow.pyc diff --git a/toolbar/project-.gif b/toolbar/project-.gif Binary files differdeleted file mode 100755 index 4050808..0000000 --- a/toolbar/project-.gif +++ /dev/null diff --git a/toolbar/project.gif b/toolbar/project.gif Binary files differdeleted file mode 100755 index ff0fe4f..0000000 --- a/toolbar/project.gif +++ /dev/null diff --git a/toolbar/projectmask.gif b/toolbar/projectmask.gif Binary files differdeleted file mode 100755 index 8092284..0000000 --- a/toolbar/projectmask.gif +++ /dev/null diff --git a/turtle.py b/turtle.py deleted file mode 100755 index dc1b0b6..0000000 --- a/turtle.py +++ /dev/null @@ -1,195 +0,0 @@ -import gtk
-from math import sin,cos,pi
-
-colors = {}
-buffer = None
-gc = None
-window = None
-width = 0
-height = 0
-sprite = None
-cm = None
-bgcolor = None
-fgcolor = None
-color = 0
-shade = 50
-pensize = 5
-pendown = True
-turtle = None
-
-DEGTOR = 2*pi/360
-
-xcor = 0
-ycor = 0
-heading = 0
-
-color_table = (
- 0xFF0000,0xFF0D00,0xFF1A00,0xFF2600,0xFF3300,0xFF4000,0xFF4D00,0xFF5900,0xFF6600,0xFF7300,
- 0xFF8000,0xFF8C00,0xFF9900,0xFFA600,0xFFB300,0xFFBF00,0xFFCC00,0xFFD900,0xFFE600,0xFFF200,
- 0xFFFF00,0xE6FF00,0xCCFF00,0xB3FF00,0x99FF00,0x80FF00,0x66FF00,0x4DFF00,0x33FF00,0x1AFF00,
- 0x00FF00,0x00FF0D,0x00FF1A,0x00FF26,0x00FF33,0x00FF40,0x00FF4D,0x00FF59,0x00FF66,0x00FF73,
- 0x00FF80,0x00FF8C,0x00FF99,0x00FFA6,0x00FFB3,0x00FFBF,0x00FFCC,0x00FFD9,0x00FFE6,0x00FFF2,
- 0x00FFFF,0x00F2FF,0x00E6FF,0x00D9FF,0x00CCFF,0x00BFFF,0x00B3FF,0x00A6FF,0x0099FF,0x008CFF,
- 0x0080FF,0x0073FF,0x0066FF,0x0059FF,0x004DFF,0x0040FF,0x0033FF,0x0026FF,0x001AFF,0x000DFF,
- 0x0000FF,0x0D00FF,0x1A00FF,0x2600FF,0x3300FF,0x4000FF,0x4D00FF,0x5900FF,0x6600FF,0x7300FF,
- 0x8000FF,0x8C00FF,0x9900FF,0xA600FF,0xB300FF,0xBF00FF,0xCC00FF,0xD900FF,0xE600FF,0xF200FF,
- 0xFF00FF,0xFF00E6,0xFF00CC,0xFF00B3,0xFF0099,0xFF0080,0xFF0066,0xFF004D,0xFF0033,0xFF001A)
-
-def init(win, spr, tspr, bg):
- global buffer, gc, window, sprite, width, height, bgcolor, fgcolor, cm, turtle
- window, sprite, buffer, turtle, bgcolor = win.window, spr, spr.image, tspr, bg
- width, height = buffer.get_size()
- gc = win.window.new_gc()
- cm = gc.get_colormap()
- gc = buffer.new_gc()
- clearscreen()
-
-def clearscreen():
- global xcor,ycor,heading, pendown
- xcor, ycor, heading = 0,0,0
- rect = gtk.gdk.Rectangle(0,0,width,height)
- gc.set_foreground(bgcolor)
- buffer.draw_rectangle(gc, True, *rect)
- inval(0,0,width,height)
- setpensize(5)
- setcolor(0)
- setshade(50)
- pendown = True
- move_turtle()
- turn_turtle()
- return None
-
-def forward(n):
- global xcor,ycor
- gc.set_foreground(fgcolor)
- oldx, oldy = xcor, ycor
- xcor += n*sin(heading*DEGTOR)
- ycor += n*cos(heading*DEGTOR)
- if pendown: draw_line(oldx,oldy,xcor,ycor)
- move_turtle()
- return None
-
-def seth(n):
- global heading
- heading=n
- heading%=360
- turn_turtle()
- return None
-
-def right(n):
- global heading
- heading+=n
- heading%=360
- turn_turtle()
- return None
-
-def arc(a,r):
- gc.set_foreground(fgcolor)
- if a<0: larc(-a,r)
- else: rarc(a,r)
- move_turtle()
- turn_turtle()
-
-def rarc(a,r):
- global xcor,ycor
- if r<0: r=-r; a=-a
- cx = xcor+r*cos(heading*DEGTOR)
- cy = ycor-r*sin(heading*DEGTOR)
- x,y,w,h=width/2+int(cx-r),height/2-int(cy+r),int(2*r),int(2*r)
- buffer.draw_arc(gc,False,x,y,w,h,int(180-heading-a)*64,int(a)*64)
- inval(x-pensize/2-3,y-pensize/2-3,w+pensize+6,h+pensize+6)
- right(a)
- xcor=cx-r*cos(heading*DEGTOR)
- ycor=cy+r*sin(heading*DEGTOR)
-
-def larc(a,r):
- global xcor,ycor
- if r<0: r=-r; a=-a
- cx = xcor-r*cos(heading*DEGTOR)
- cy = ycor+r*sin(heading*DEGTOR)
- x,y,w,h=width/2+int(cx-r),height/2-int(cy+r),int(2*r),int(2*r)
- buffer.draw_arc(gc,False,x,y,w,h,int(360-heading)*64,int(a)*64)
- inval(x-pensize/2-3,y-pensize/2-3,w+pensize+6,h+pensize+6)
- right(-a)
- xcor=cx+r*cos(heading*DEGTOR)
- ycor=cy-r*sin(heading*DEGTOR)
-
-def setxy(x,y):
- global xcor,ycor
- xcor,ycor = x,y
- move_turtle()
-
-def setpensize(ps):
- global pensize
- pensize = ps
- gc.set_line_attributes(int(pensize),gtk.gdk.LINE_SOLID,gtk.gdk.CAP_ROUND,gtk.gdk.JOIN_MITER)
- return None
-
-def setcolor(c):
- global color
- color = c
- set_fgcolor()
- return None
-
-def setshade(s):
- global shade
- shade = s
- set_fgcolor()
- return None
-
-def fillscreen(c,s):
- oldc, olds = color,shade
- setcolor(c); setshade(s)
- rect = gtk.gdk.Rectangle(0,0,width,height)
- gc.set_foreground(fgcolor)
- buffer.draw_rectangle(gc, True, *rect)
- inval(0,0,width,height)
- setcolor(oldc); setshade(olds)
- return None
-
-def set_fgcolor():
- global fgcolor
- sh = (wrap100(shade)-50)/50.0
- rgb = color_table[wrap100(color)]
- r,g,b = (rgb>>8)&0xff00,rgb&0xff00,(rgb<<8)&0xff00
- r,g,b = calc_shade(r,sh),calc_shade(g,sh),calc_shade(b,sh)
- fgcolor = cm.alloc_color(r,g,b)
-
-def wrap100(n):
- n = int(n)
- n %= 200
- if n>99: n=199-n
- return n
-
-def calc_shade(c,s):
- if s<0: return int(c*(1+s*.8))
- return int(c+(65536-c)*s*.9)
-
-def setpen(bool):
- global pendown
- pendown = bool
-
-def draw_line(x1,y1,x2,y2):
- x1,y1 = width/2+int(x1), height/2-int(y1)
- x2,y2 = width/2+int(x2), height/2-int(y2)
- if x1<x2: minx,maxx=x1,x2
- else: minx,maxx=x2,x1
- if y1<y2: miny,maxy=y1,y2
- else: miny,maxy=y2,y1
- w,h=maxx-minx,maxy-miny
- buffer.draw_line(gc,x1,y1,x2,y2)
- inval(minx-pensize/2-3,miny-pensize/2-3,w+pensize+6,h+pensize+6)
-
-def turn_turtle():
- turtle.setshape(shapelist[(int(heading+5)%360)/10])
-
-def move_turtle():
- x,y = width/2+int(xcor), height/2-int(ycor)
- turtle.move((sprite.x+x-30,sprite.y+y-30))
- inval(x-30,y-30,60,60)
-
-def inval(x,y,w,h):
- rect = gtk.gdk.Rectangle(int(x+sprite.x),int(y+sprite.y),int(w),int(h))
- window.invalidate_rect(rect, False)
-
-
diff --git a/turtleart.py b/turtleart.py new file mode 100755 index 0000000..3b698a6 --- /dev/null +++ b/turtleart.py @@ -0,0 +1,22 @@ +import pygtk +pygtk.require('2.0') +import gtk +import gobject +import os +import os.path + +from tawindow import * + +def main(): + win1 = gtk.Window(gtk.WINDOW_TOPLEVEL) + twNew(win1, os.path.abspath('.')) + win1.connect("destroy", lambda w: gtk.main_quit()) +# win2 = gtk.Window(gtk.WINDOW_TOPLEVEL) +# twNew(win2, os.path.abspath('.')) + gtk.main() + return 0 + +if __name__ == "__main__": + main() + + |