diff options
author | Karl Berry <karl@freefriends.org> | 2013-04-07 18:19:31 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2013-04-07 18:19:31 +0000 |
commit | 752012c605d34cd943795527a9738475a6958fcc (patch) | |
tree | 4ee06acdd8333a662c2d6f6ef716235053468f55 /Master/texmf-dist/asymptote/GUI/xasy2asy.py | |
parent | 9789d09132f18a838e84f041b4b3aff28d3426ec (diff) |
texmf -> texmf-dist: start with unique dirs from texmf
git-svn-id: svn://tug.org/texlive/trunk@29712 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/asymptote/GUI/xasy2asy.py')
-rwxr-xr-x | Master/texmf-dist/asymptote/GUI/xasy2asy.py | 767 |
1 files changed, 767 insertions, 0 deletions
diff --git a/Master/texmf-dist/asymptote/GUI/xasy2asy.py b/Master/texmf-dist/asymptote/GUI/xasy2asy.py new file mode 100755 index 00000000000..7779e073f81 --- /dev/null +++ b/Master/texmf-dist/asymptote/GUI/xasy2asy.py @@ -0,0 +1,767 @@ +#!/usr/bin/env python +########################################################################### +# +# xasy2asy provides a Python interface to Asymptote +# +# +# Author: Orest Shardt +# Created: June 29, 2007 +# +########################################################################### +import sys,os,signal,threading +from subprocess import * +from string import * +import xasyOptions +import Queue +from Tkinter import * +from tempfile import mkdtemp + +# PIL support is now mandatory due to rotations +try: + import ImageTk + import Image +except: + pass + +import CubicBezier + +quickAsyFailed = True +global AsyTempDir + +console=None + +def startQuickAsy(): + global quickAsy + global quickAsyFailed + global AsyTempDir + global fout,fin + if quickAsyRunning(): + return + try: + fout.close() + quickAsy.wait() + except: + pass + try: + quickAsyFailed = False + if os.name == "nt": + AsyTempDir=mkdtemp(prefix="asy_", dir="./") + else: + AsyTempDir=mkdtemp(prefix="asy_")+os.sep + if sys.platform[:3] == 'win': + quickAsy=Popen([xasyOptions.options['asyPath'],"-noV","-multiline","-q", + "-o"+AsyTempDir,"-inpipe=0","-outpipe=2"],stdin=PIPE,stderr=PIPE) + fout=quickAsy.stdin + fin=quickAsy.stderr + else: + (rx,wx) = os.pipe() + (ra,wa) = os.pipe() + quickAsy=Popen([xasyOptions.options['asyPath'],"-noV","-multiline","-q", + "-o"+AsyTempDir,"-inpipe="+str(rx),"-outpipe="+str(wa)]) + fout=os.fdopen(wx,'w') + fin=os.fdopen(ra,'r') + if quickAsy.returncode != None: + quickAsyFailed = True + except: + quickAsyFailed = True + +def getAsyTempDir(): + return AsyTempDir + +def quickAsyRunning(): + if quickAsyFailed or quickAsy.returncode != None: + return False + else: + return True + +def asyExecute(command): + if not quickAsyRunning(): + startQuickAsy() + fout.write(command) + +def closeConsole(event): + global console + console = None + +def consoleOutput(line): + global console + global ctl + if console == None: + ctl=Toplevel() + ctl.title("Asymptote Console") + ctl.bind("<Destroy>",closeConsole) + yscrollbar=Scrollbar(ctl) + yscrollbar.pack(side=RIGHT,fill=Y) + console=Text(ctl,yscrollcommand=yscrollbar.set) + console.pack() + yscrollbar.config(command=console.yview) + console.insert(END,line) + ctl.lift() + +class asyTransform: + """A python implementation of an asy transform""" + def __init__(self,initTuple,delete=False): + """Initialize the transform with a 6 entry tuple""" + if type(initTuple) == type((0,)) and len(initTuple) == 6: + self.t = initTuple + self.x,self.y,self.xx,self.xy,self.yx,self.yy = initTuple + self.deleted = delete + else: + raise Exception,"Illegal initializer for asyTransform" + + def getCode(self): + """Obtain the asy code that represents this transform""" + if self.deleted: + return str(self.t) + ", false" + else: + return str(self.t) + + def scale(self,s): + return asyTransform((0,0,s,0,0,s))*self + + def __str__(self): + """Equivalent functionality to getCode(). It allows the expression str(asyTransform) to be meaningful.""" + return self.getCode() + + def __mul__(self,other): + """Define multiplication of transforms as composition.""" + if type(other)==type((0,)): + if len(other) == 6: + return self*asyTransform(other) + elif len(other) == 2: + return ((self.t[0]+self.t[2]*other[0]+self.t[3]*other[1]),(self.t[1]+self.t[4]*other[0]+self.t[5]*other[1])) + else: + raise Exception, "Illegal multiplier of %s"%str(type(other)) + elif isinstance(other,asyTransform): + result = asyTransform((0,0,0,0,0,0)) + result.x = self.x+self.xx*other.x+self.xy*other.y + result.y = self.y+self.yx*other.x+self.yy*other.y + result.xx = self.xx*other.xx+self.xy*other.yx + result.xy = self.xx*other.xy+self.xy*other.yy + result.yx = self.yx*other.xx+self.yy*other.yx + result.yy = self.yx*other.xy+self.yy*other.yy + result.t = (result.x,result.y,result.xx,result.xy,result.yx,result.yy) + return result + else: + raise Exception, "Illegal multiplier of %s"%str(type(other)) + +def identity(): + return asyTransform((0,0,1,0,0,1)) + +class asyObj: + """A base class for asy objects: an item represented by asymptote code.""" + def __init__(self): + """Initialize the object""" + self.asyCode = "" + + def updateCode(self,mag=1.0): + """Update the object's code: should be overriden.""" + pass + + def getCode(self): + """Return the code describing the object""" + self.updateCode() + return self.asyCode + +class asyPen(asyObj): + """A python wrapper for an asymptote pen""" + def __init__(self,color=(0,0,0),width=0.5,options=""): + """Initialize the pen""" + asyObj.__init__(self) + self.options=options + self.width=width + self.setColor(color) + self.updateCode() + if options != "": + self.computeColor() + + def updateCode(self,mag=1.0): + """Generate the pen's code""" + self.asyCode = "rgb(%g,%g,%g)"%self.color+"+"+str(self.width) + if len(self.options) > 0: + self.asyCode += "+"+self.options + + def setWidth(self,newWidth): + """Set the pen's width""" + self.width=newWidth + self.updateCode() + + def setColor(self,color): + """Set the pen's color""" + if type(color) == type((1,)) and len(color) == 3: + self.color = color + else: + self.color = "(0,0,0)" + self.updateCode() + + def computeColor(self): + """Find out the color of an arbitrary asymptote pen.""" + fout.write("pen p="+self.getCode()+';\n') + fout.write("file fout=output(mode='pipe');\n") + fout.write("write(fout,colorspace(p),newl);\n") + fout.write("write(fout,colors(p));\n") + fout.write("flush(fout);\n") + fout.flush() + colorspace = fin.readline() + if colorspace.find("cmyk") != -1: + lines = fin.readline()+fin.readline()+fin.readline()+fin.readline() + parts = lines.split() + c,m,y,k = eval(parts[0]),eval(parts[1]),eval(parts[2]),eval(parts[3]) + k = 1-k + r,g,b = ((1-c)*k,(1-m)*k,(1-y)*k) + elif colorspace.find("rgb") != -1: + lines = fin.readline()+fin.readline()+fin.readline() + parts = lines.split() + r,g,b = eval(parts[0]),eval(parts[1]),eval(parts[2]) + elif colorspace.find("gray") != -1: + lines = fin.readline() + parts = lines.split() + r = g = b = eval(parts[0]) + self.color = (r,g,b) + + def tkColor(self): + """Return the tk version of the pen's color""" + self.computeColor() + r,g,b = self.color + r,g,b = int(256*r),int(256*g),int(256*b) + if r == 256: + r = 255 + if g == 256: + g = 255 + if b == 256: + b = 255 + r,g,b = map(hex,(r,g,b)) + r,g,b = r[2:],g[2:],b[2:] + if len(r) < 2: + r += '0' + if len(g) < 2: + g += '0' + if len(b) < 2: + b += '0' + return'#'+r+g+b + +class asyPath(asyObj): + """A python wrapper for an asymptote path""" + def __init__(self): + """Initialize the path to be an empty path: a path with no nodes, control points, or links.""" + asyObj.__init__(self) + self.nodeSet = [] + self.linkSet = [] + self.controlSet = [] + self.computed = False + + def initFromNodeList(self,nodeSet,linkSet): + """Initialize the path from a set of nodes and link types, "--", "..", or "::" """ + if len(nodeSet)>0: + self.nodeSet = nodeSet[:] + self.linkSet = linkSet[:] + self.computed = False + + def initFromControls(self,nodeSet,controlSet): + """Initialize the path from nodes and control points""" + self.controlSet = controlSet[:] + self.nodeSet = nodeSet[:] + self.computed = True + + def makeNodeStr(self,node): + """Represent a node as a string""" + if node == 'cycle': + return node + else: + return "("+str(node[0])+","+str(node[1])+")" + + def updateCode(self,mag=1.0): + """Generate the code describing the path""" + if not self.computed: + count = 0 + #this string concatenation could be optimised + self.asyCode = self.makeNodeStr(self.nodeSet[0]) + for node in self.nodeSet[1:]: + self.asyCode += self.linkSet[count]+self.makeNodeStr(node) + count += 1 + else: + count = 0 + #this string concatenation could be optimised + self.asyCode = self.makeNodeStr(self.nodeSet[0]) + for node in self.nodeSet[1:]: + self.asyCode += "..controls" + self.asyCode += self.makeNodeStr(self.controlSet[count][0]) + self.asyCode += "and" + self.asyCode += self.makeNodeStr(self.controlSet[count][1]) + self.asyCode += ".." + self.makeNodeStr(node) + "\n" + count += 1 + + def getNode(self,index): + """Return the requested node""" + return self.nodeSet[index] + + def getLink(self,index): + """Return the requested link""" + return self.linkSet[index] + + def setNode(self,index,newNode): + """Set a node to a new position""" + self.nodeSet[index] = newNode + + def moveNode(self,index,offset): + """Translate a node""" + if self.nodeSet[index] != "cycle": + self.nodeSet[index] = (self.nodeSet[index][0]+offset[0],self.nodeSet[1]+offset[1]) + + def setLink(self,index,ltype): + """Change the specified link""" + self.linkSet[index] = ltype + + def addNode(self,point,ltype): + """Add a node to the end of a path""" + self.nodeSet.append(point) + if len(self.nodeSet) != 1: + self.linkSet.append(ltype) + if self.computed: + self.computeControls() + + def insertNode(self,index,point,ltype=".."): + """Insert a node, and its corresponding link, at the given index""" + self.nodeSet.insert(index,point) + self.linkSet.insert(index,ltype) + if self.computed: + self.computeControls() + + def setControl(self,index,position): + """Set a control point to a new position""" + self.controlSet[index] = position + + def moveControl(self,index,offset): + """Translate a control point""" + self.controlSet[index] = (self.controlSet[index][0]+offset[0],self.controlSet[index][1]+offset[1]) + + def computeControls(self): + """Evaluate the code of the path to obtain its control points""" + fout.write("file fout=output(mode='pipe');\n") + fout.write("path p="+self.getCode()+';\n') + fout.write("write(fout,length(p),newl);\n") + fout.write("write(fout,unstraighten(p),endl);\n") + fout.flush() + lengthStr = fin.readline() + pathSegments = eval(lengthStr.split()[-1]) + pathStrLines = [] + for i in range(pathSegments+1): + line=fin.readline() + line=line.replace("\n","") + pathStrLines.append(line) + oneLiner = "".join(split(join(pathStrLines))) + splitList = oneLiner.split("..") + nodes = [a for a in splitList if a.find("controls")==-1] + self.nodeSet = [] + for a in nodes: + if a == 'cycle': + self.nodeSet.append(a) + else: + self.nodeSet.append(eval(a)) + controls = [a.replace("controls","").split("and") for a in splitList if a.find("controls") != -1] + self.controlSet = [[eval(a[0]),eval(a[1])] for a in controls] + self.computed = True + +class asyLabel(asyObj): + """A python wrapper for an asy label""" + def __init__(self,text="",location=(0,0),pen=asyPen()): + """Initialize the label with the given test, location, and pen""" + asyObj.__init__(self) + self.text = text + self.location = location + self.pen = pen + + def updateCode(self,mag=1.0): + """Generate the code describing the label""" + self.asyCode = "Label(\""+self.text+"\","+str((self.location[0],self.location[1]))+","+self.pen.getCode()+",align=SE)" + + def setText(self,text): + """Set the label's text""" + self.text = text + self.updateCode() + + def setPen(self,pen): + """Set the label's pen""" + self.pen = pen + self.updateCode() + + def moveTo(self,newl): + """Translate the label's location""" + self.location = newl + +class asyImage: + """A structure containing an image and its format, bbox, and IDTag""" + def __init__(self,image,format,bbox): + self.image = image + self.format = format + self.bbox = bbox + self.IDTag = None + +class xasyItem: + """A base class for items in the xasy GUI""" + def __init__(self,canvas=None): + """Initialize the item to an empty item""" + self.transform = [identity()] + self.asyCode = "" + self.imageList = [] + self.IDTag = None + self.asyfied = False + self.onCanvas = canvas + + def updateCode(self,mag=1.0): + """Update the item's code: to be overriden""" + pass + + def getCode(self): + """Return the code describing the item""" + self.updateCode() + return self.asyCode + + def handleImageReception(self,file,format,bbox,count): + """Receive an image from an asy deconstruction. It replaces the default in asyProcess.""" + image = Image.open(file) + self.imageList.append(asyImage(image,format,bbox)) + if self.onCanvas != None: + self.imageList[-1].itk = ImageTk.PhotoImage(image) + self.imageList[-1].originalImage = image.copy() + self.imageList[-1].originalImage.theta = 0.0 + self.imageList[-1].originalImage.bbox = bbox + if count >= len(self.transform) or self.transform[count].deleted == False: + self.imageList[-1].IDTag = self.onCanvas.create_image(bbox[0],-bbox[3],anchor=NW,tags=("image"),image=self.imageList[-1].itk) + self.onCanvas.update() + + def asyfy(self,mag=1.0): + self.removeFromCanvas() + self.imageList = [] + self.imageHandleQueue = Queue.Queue() + worker = threading.Thread(target=self.asyfyThread,args=(mag,)) + worker.start() + item = self.imageHandleQueue.get() + if console != None: + console.delete(1.0,END) + while item != (None,) and item[0] != "ERROR": + if(item[0] == "OUTPUT"): + consoleOutput(item[1]) + else: + self.handleImageReception(*item) + try: + os.remove(item[0]) + except: + pass + item = self.imageHandleQueue.get() + #self.imageHandleQueue.task_done() + worker.join() + + def asyfyThread(self,mag=1.0): + """Convert the item to a list of images by deconstructing this item's code""" + fout.write("reset;\n") + fout.write("initXasyMode();\n") + fout.write("atexit(null);\n") + global console + for line in self.getCode().splitlines(): + fout.write(line+"\n"); + fout.write("deconstruct(%f);\n"%mag) + fout.flush() + format = "png" + maxargs = int(split(fin.readline())[0]) + boxes=[] + batch=0 + n=0 + text = fin.readline() + template=AsyTempDir+"%d_%d.%s" + def render(): + for i in range(len(boxes)): + l,b,r,t = [float(a) for a in split(boxes[i])] + name=template%(batch,i+1,format) + self.imageHandleQueue.put((name,format,(l,b,r,t),i)) + while text != "Done\n" and text != "Error\n": + boxes.append(text) + text = fin.readline() + n += 1 + if n >= maxargs: + render() + boxes=[] + batch += 1 + n=0 + if text == "Error\n": + self.imageHandleQueue.put(("ERROR",fin.readline())) + else: + render() + self.imageHandleQueue.put((None,)) + self.asyfied = True + + def drawOnCanvas(self,canvas,mag,forceAddition=False): + pass + def removeFromCanvas(self): + pass + +class xasyDrawnItem(xasyItem): + """A base class for GUI items was drawn by the user. It combines a path, a pen, and a transform.""" + def __init__(self,path,pen = asyPen(),transform = identity()): + """Initialize the item with a path, pen, and transform""" + xasyItem.__init__(self) + self.path = path + self.pen = pen + self.transform = [transform] + + def appendPoint(self,point,link=None): + """Append a point to the path. If the path is cyclic, add this point before the 'cycle' node.""" + if self.path.nodeSet[-1] == 'cycle': + self.path.nodeSet[-1] = point + self.path.nodeSet.append('cycle') + else: + self.path.nodeSet.append(point) + self.path.computed = False + if len(self.path.nodeSet) > 1 and link != None: + self.path.linkSet.append(link) + + def clearTransform(self): + """Reset the item's transform""" + self.transform = [identity()] + + def removeLastPoint(self): + """Remove the last point in the path. If the path is cyclic, remove the node before the 'cycle' node.""" + if self.path.nodeSet[-1] == 'cycle': + del self.path.nodeSet[-2] + else: + del self.path.nodeSet[-1] + del self.path.linkSet[-1] + self.path.computed = False + + def setLastPoint(self,point): + """Modify the last point in the path. If the path is cyclic, modify the node before the 'cycle' node.""" + if self.path.nodeSet[-1] == 'cycle': + self.path.nodeSet[-2] = point + else: + self.path.nodeSet[-1] = point + self.path.computed = False + +class xasyShape(xasyDrawnItem): + """An outlined shape drawn on the GUI""" + def __init__(self,path,pen=asyPen(),transform=identity()): + """Initialize the shape with a path, pen, and transform""" + xasyDrawnItem.__init__(self,path,pen,transform) + + def updateCode(self,mag=1.0): + """Generate the code to describe this shape""" + self.asyCode = "xformStack.push("+self.transform[0].getCode()+");\n" + self.asyCode += "draw("+self.path.getCode()+","+self.pen.getCode()+");" + + def removeFromCanvas(self,canvas): + """Remove the shape's depiction from a tk canvas""" + if self.IDTag != None: + canvas.delete(self.IDTag) + + def drawOnCanvas(self,canvas,mag,asyFy=False,forceAddition=False): + """Add this shape to a tk canvas""" + if not asyFy: + if self.IDTag == None or forceAddition: + #add ourselves to the canvas + self.path.computeControls() + self.IDTag = canvas.create_line(0,0,0,0,tags=("drawn","xasyShape"),fill=self.pen.tkColor(),width=self.pen.width*mag) + self.drawOnCanvas(canvas,mag) + else: + self.path.computeControls() + pointSet = [] + previousNode = self.path.nodeSet[0] + nodeCount = 0 + if len(self.path.nodeSet) == 0: + pointSet = [0,0,0,0] + elif len(self.path.nodeSet) == 1: + if self.path.nodeSet[-1] != 'cycle': + p = self.transform[0]*(self.path.nodeSet[0][0],self.path.nodeSet[0][1]) + pointSet = [p[0],-p[1],p[0],-p[1],p[0],-p[1]] + else: + pointSet = [0,0,0,0] + else: + for node in self.path.nodeSet[1:]: + if node == 'cycle': + node = self.path.nodeSet[0] + transform = self.transform[0].scale(mag) + points = CubicBezier.makeBezier(transform*previousNode,transform*self.path.controlSet[nodeCount][0],transform*self.path.controlSet[nodeCount][1],transform*node) + for point in points: + pointSet += [point[0],-point[1]] + nodeCount += 1 + previousNode = node + canvas.coords(self.IDTag,*pointSet) + canvas.itemconfigure(self.IDTag,fill=self.pen.tkColor(),width=self.pen.width*mag) + else: + #first asyfy then add an image list + pass + + def __str__(self): + """Create a string describing this shape""" + return "xasyShape code:%s"%("\n\t".join(self.getCode().splitlines())) + +class xasyFilledShape(xasyShape): + """A filled shape drawn on the GUI""" + def __init__(self,path,pen=asyPen(),transform=identity()): + """Initialize this shape with a path, pen, and transform""" + if path.nodeSet[-1] != 'cycle': + raise Exception,"Filled paths must be cyclic" + xasyShape.__init__(self,path,pen,transform) + + def updateCode(self,mag=1.0): + """Generate the code describing this shape""" + self.asyCode = "xformStack.push("+self.transform[0].getCode()+");\n" + self.asyCode += "fill("+self.path.getCode()+","+self.pen.getCode()+");" + + def removeFromCanvas(self,canvas): + """Remove this shape's depiction from a tk canvas""" + if self.IDTag != None: + canvas.delete(self.IDTag) + + def drawOnCanvas(self,canvas,mag,asyFy=False,forceAddition=False): + """Add this shape to a tk canvas""" + if not asyFy: + if self.IDTag == None or forceAddition: + #add ourselves to the canvas + self.path.computeControls() + self.IDTag = canvas.create_polygon(0,0,0,0,0,0,tags=("drawn","xasyFilledShape"),fill=self.pen.tkColor(),outline=self.pen.tkColor(),width=1*mag) + self.drawOnCanvas(canvas,mag) + else: + self.path.computeControls() + pointSet = [] + previousNode = self.path.nodeSet[0] + nodeCount = 0 + if len(self.path.nodeSet) == 0: + pointSet = [0,0,0,0,0,0] + elif len(self.path.nodeSet) == 1: + if self.path.nodeSet[-1] != 'cycle': + p = self.transform[0]*(self.path.nodeSet[0][0],self.path.nodeSet[0][1]) + pointSet = [p[0],-p[1],p[0],-p[1],p[0],-p[1]] + else: + pointSet = [0,0,0,0,0,0] + elif len(self.path.nodeSet) == 2: + if self.path.nodeSet[-1] != 'cycle': + p = self.transform[0].scale(mag)*(self.path.nodeSet[0][0],self.path.nodeSet[0][1]) + p2 = self.transform[0].scale(mag)*(self.path.nodeSet[1][0],self.path.nodeSet[1][1]) + pointSet = [p[0],-p[1],p2[0],-p2[1],p[0],-p[1]] + else: + pointSet = [0,0,0,0,0,0] + else: + for node in self.path.nodeSet[1:]: + if node == 'cycle': + node = self.path.nodeSet[0] + transform = self.transform[0].scale(mag) + points = CubicBezier.makeBezier(transform*previousNode,transform*self.path.controlSet[nodeCount][0],transform*self.path.controlSet[nodeCount][1],transform*node) + for point in points: + pointSet += [point[0],-point[1]] + nodeCount += 1 + previousNode = node + canvas.coords(self.IDTag,*pointSet) + canvas.itemconfigure(self.IDTag,fill=self.pen.tkColor(),outline=self.pen.tkColor(),width=1*mag) + else: + #first asyfy then add an image list + pass + + def __str__(self): + """Return a string describing this shape""" + return "xasyFilledShape code:%s"%("\n\t".join(self.getCode().splitlines())) + +class xasyText(xasyItem): + """Text created by the GUI""" + def __init__(self,text,location,pen=asyPen(),transform=identity()): + """Initialize this item with text, a location, pen, and transform""" + xasyItem.__init__(self) + self.label=asyLabel(text,location,pen) + self.transform = [transform] + self.onCanvas = None + + def updateCode(self,mag=1.0): + """Generate the code describing this object""" + self.asyCode = "xformStack.push("+self.transform[0].getCode()+");\n" + self.asyCode += "label("+self.label.getCode()+");" + + def removeFromCanvas(self): + """Removes the label's images from a tk canvas""" + if self.onCanvas == None: + return + for image in self.imageList: + if image.IDTag != None: + self.onCanvas.delete(image.IDTag) + + def drawOnCanvas(self,canvas,mag,asyFy=True,forceAddition=False): + """Adds the label's images to a tk canvas""" + if self.onCanvas == None: + self.onCanvas = canvas + elif self.onCanvas != canvas: + raise Exception,"Error: item cannot be added to more than one canvas" + self.asyfy(mag) + + def __str__(self): + return "xasyText code:%s"%("\n\t".join(self.getCode().splitlines())) + +class xasyScript(xasyItem): + """A set of images create from asymptote code. It is always deconstructed.""" + def __init__(self,canvas,script="",transforms=[]): + """Initialize this script item""" + xasyItem.__init__(self,canvas) + self.transform = transforms[:] + self.script = script + + def clearTransform(self): + """Reset the transforms for each of the deconstructed images""" + self.transform = [identity() for im in self.imageList] + + def updateCode(self,mag=1.0): + """Generate the code describing this script""" + self.asyCode = ""; + if len(self.transform) > 0: + self.asyCode = "xformStack.add(" + isFirst = True + count = 0 + for xform in self.transform: + if not isFirst: + self.asyCode+=",\n" + self.asyCode += "indexedTransform(%d,%s)"%(count,str(xform)) + isFirst = False + count += 1 + self.asyCode += ");\n" + self.asyCode += "startScript(); {\n" + self.asyCode += self.script.replace("\t"," ") + self.asyCode = self.asyCode.rstrip() + self.asyCode += "\n} endScript();\n" + + def setScript(self,script): + """Sets the content of the script item.""" + self.script = script + self.updateCode() + + def removeFromCanvas(self): + """Removes the script's images from a tk canvas""" + if self.onCanvas == None: + return + for image in self.imageList: + if image.IDTag != None: + self.onCanvas.delete(image.IDTag) + + def asyfy(self,mag): + """Generate the list of images described by this object and adjust the length of the transform list.""" + xasyItem.asyfy(self,mag) + while len(self.imageList) > len(self.transform): + self.transform.append(identity()) + while len(self.imageList) < len(self.transform): + self.transform.pop() + self.updateCode() + + def drawOnCanvas(self,canvas,mag,asyFy=True,forceAddition=False): + """Adds the script's images to a tk canvas""" + if self.onCanvas == None: + self.onCanvas = canvas + elif self.onCanvas != canvas: + raise Exception,"Error: item cannot be added to more than one canvas" + self.asyfy(mag) + + def __str__(self): + """Return a string describing this script""" + retVal = "xasyScript\n\tTransforms:\n" + for xform in self.transform: + retVal += "\t"+str(xform)+"\n" + retVal += "\tCode Ommitted" + return retVal + +if __name__=='__main__': + root = Tk() + t=xasyText("test",(0,0)) + t.asyfy() |