summaryrefslogtreecommitdiff
path: root/graphics/tktexcad/picels.py
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/tktexcad/picels.py')
-rw-r--r--graphics/tktexcad/picels.py1299
1 files changed, 1299 insertions, 0 deletions
diff --git a/graphics/tktexcad/picels.py b/graphics/tktexcad/picels.py
new file mode 100644
index 0000000000..f8846cc1e0
--- /dev/null
+++ b/graphics/tktexcad/picels.py
@@ -0,0 +1,1299 @@
+# TkTeXCad
+# (C) Copyright 2001 Hilmar Straube; dieses Programm untersteht der GPL.
+# Keinerlei Garantie auf was auch immer, was mit diesem Programm zu tun hat.
+
+from Tkinter import *
+import math
+
+from internat import * # Sprache und Konfiguration auch hier benutzen
+from config import *
+from globalpars import *
+
+fakt = FAKT
+
+CLIPBOARDNAME = None # gesichert als Name des Clipboard
+
+def notifyfaktchange(newfakt):
+ global fakt
+ fakt = newfakt
+
+class diameter: # Sucht einen passenden Durchmesser zu gegebenem
+ def getd(self, d, as):
+ index = 0
+ if as:
+ pd = POSSIBLEDIAMETERSAS
+ else:
+ pd = POSSIBLEDIAMETERS
+ while pd[index] < d:
+ index += 1
+ if index >= len(pd) - 1:
+ return pd[index]
+
+ if index == 0: # index - 1 gibt Ärger!
+ return pd[0]
+ if abs(pd[index] - d) < abs(pd[index - 1] - d):
+ return pd[index]
+ else:
+ return pd[index - 1]
+
+diameterer = diameter()
+
+class angle: # Klasse zum Bestimmen eines besten LaTeX-Paares zu einem gegebenen Winkel
+ def __init__(self, set):
+ self.erg = []
+ for dxdy in set:
+ if dxdy != (0, 1):
+ m = dxdy[1]/float(dxdy[0])
+ alpha = math.atan(m)
+ self.erg.append([alpha, dxdy])
+ else:
+ self.erg.append([math.pi/2, dxdy])
+ def getdxdy(self, alpha): # Winkel im Bereich [0; pi/2]
+ dev = -1
+ index = -1
+ z = 0
+ for el in self.erg:
+ aktudev = abs(el[0] - alpha)
+ if aktudev < dev or index == -1:
+ index = z
+ dev = aktudev
+ z += 1
+ return self.erg[index]
+
+angler = angle(POSSIBLEDXDY) # Für allg. Benutzung
+vecangler = angle(VECDXDY) # Für Pfeile
+
+class picelEx(Exception):
+ pass
+
+class picel:
+ # Basisklasse für alle Bildelemente; jedes muss sich aus Parametern erzeugen lassen,
+ # Sich selbst zeichnen, für sich in uids alle dabei benutzten ids sichern und diese an den Aufrufer zurückliefern.
+ # Grund: picel1 ist in putter1 ist in picture1 ist in putter2 ist in picture2 ist in Oberfläche
+ # Oberflächer liefert id, und picture kann sagen, dass diese in putter2, in ... -> Rückschluss
+ def __init__(self):
+ self.uids = []
+ def undrawhook(self):
+ pass
+ def draw(self): # WIRD NICHT AUFGERUFEN! Nur zur Hilfestellung.
+ self.uids = []
+ return self.uids
+
+class pcs: # Klasse zur Verwaltung aller Teilbildklassen und ihrer Namen
+ def __init__(self):
+ self.pictures = []
+ self.names = []
+ def append(self, item):
+ self.pictures.append(item)
+ self.names.append(item.name)
+ def __delitem__(self, nr):
+ del self.pictures[nr]
+ del self.names[nr]
+ def newname(self, name):
+ return not(name in self.names)
+ def changename(self, oldname, newname):
+ try:
+ index = self.names.index(oldname)
+ self.names[index] = newname
+ self.pictures[index].name = newname
+ return 1
+ except ValueError:
+ return 0
+
+def plboundingbox(putterlist):
+ "Bestimmt Extremausmaße der enthaltenen Elemente und setzt dann die eigenen entsprechend"
+ x1 = x2 = y1 = y2 = None # Umschließendes Rechteck feststellen
+ for el in putterlist:
+ dx1, dy1, dx2, dy2 = el.dxdy()
+ if x1 > dx1 or x1 == None:
+ x1 = dx1
+ if x2 < dx2 or x2 == None:
+ x2 = dx2
+ if y1 > dy1 or y1 == None:
+ y1 = dy1
+ if y2 < dy2 or y2 == None:
+ y2 = dy2
+
+ return (x1, y1, x2, y2)
+
+class pictureEx(picelEx):
+ pass
+
+class pictureclass:
+ def dumptex(self):
+ sf = '% ' + PROGNAME + GENMARK[LANG]
+ sf += '\\begin{picture}' + `(self.xsize, self.ysize)` + '\n'
+ for el in self.putters:
+ sf += el.dumptex() + '\n'
+ sf += '\\end{picture}'
+ return sf
+ def __init__(self, xsize, ysize, name):
+ if xsize < 0 or ysize < 0:
+ raise pictureEx
+ self.xsize = xsize
+ self.ysize = ysize
+ self.name = name
+ self.putters = []
+ def untk(self): # Alle Elemente, die mit tk beginnen, können nicht gepickelt werden, werden also vorher gelöscht.
+ # Diese Prozedur muss für jede zu pickelnde Klasse aufgerufen werden
+ for putter in self.putters:
+ keys = putter.__dict__.keys()
+ for key in keys:
+ if key[:2] == 'tk':
+ del putter.__dict__[key]
+ keys = putter.pe.__dict__.keys()
+ for key in keys:
+ if key[:2] == 'tk':
+ del putter.pe.__dict__[key]
+ def getallblocks(self, ofpc, root = None):
+ # Die Methode liefert alle Klassen, deren Instanzen in dem Baum von self ofpc enthalten.
+
+ if root == None: # Baumausgang sichern
+ root = self
+
+ blocked = []
+ for putter in self.putters: # Alle Putter der Klasse durchlaufen
+ if putter.pe.__class__ == picture:
+ # Dieser putter ist ein Bild.
+ if putter.pe.pc == ofpc: # Ist Putter picture und Instanz der gefragten Klasse
+ bc = putter.pe.bc
+ if bc not in blocked: # ... hänge alle noch nicht blockierten Klassen an
+ blocked.append(bc)
+ erg = root.getallblocks(bc) # Geh den Baum nochmal durch: Alle Klassen, die enthaltende enthalten sind ebenfalls zu blockieren.
+ for el in erg: # Dopplungen vermeiden
+ if el not in blocked:
+ blocked.append(el)
+ else:
+ # Der Baum spaltet sich auf; das picel im putter ist ein anderes Bild
+ erg = putter.pe.pc.getallblocks(ofpc, root) # Hereingehen.
+ for el in erg:
+ if el not in blocked:
+ blocked.append(el)
+ return blocked # Rückgabe
+ def adjustdxdy(self): # Minimale Abmessungen bestimmen und benutzen; nicht wenn kein Putter da ist.
+ if self.putters != []:
+ x1, y1, x2, y2 = plboundingbox(self.putters)
+ for z in range(len(self.putters)):
+ self.putters[z].x -= x1
+ self.putters[z].y -= y1
+ self.xsize = x2 - x1
+ self.ysize = y2 - y1
+
+class picture(picel):
+ clickdepth = 1
+ def dumptex(self):
+ return '\\setlength{\\unitlength}{' + `self.scale`+ '\\unitlength}\\input{' + self.pc.name + '}'
+ def __init__(self, pc, scale, blockedclasses):
+ # letzter Parameter: Liste der Klassen, in deren Instanzen das neue Bild enthalten ist
+ self.pc = pc
+ self.putters = self.pc.putters
+ self.bc = blockedclasses
+ self.scale = scale
+ def dxdy(self, x, y):
+ return x, y, x + self.pc.xsize, x + self.pc.ysize
+ def copy(self):
+ return picture(self.pc, self.scale, self.bc)
+ def changecb(self, event = None):
+ try:
+ self.scale = self.tkscale.get() / 100.0
+ self.tkcallredraw()
+ except ValueError:
+ self.tkscale.set(self.scale)
+ def change(self, frame, tkcallredraw):
+ self.tkcallredraw = tkcallredraw
+ Label(frame, text = PICTURELABELCLASS[LANG] + self.pc.name).grid(row = 0, columnspan = 2)
+ Label(frame, text = PICTURELABELSCALE[LANG]).grid(row = 1, column = 0)
+ self.tkscale = DoubleVar()
+ self.tkscale.set(self.scale * 100)
+ e = Entry(frame, textvariable = self.tkscale)
+ e.grid(row = 1, column = 1, sticky = E + W)
+ e.bind("<Return>", self.changecb)
+ def doscale(self, scale):
+ self.scale *= scale
+ def draw(self, x, y, maxy, canvas, scale = 1):
+ self.uids = []
+ for putter in self.putters:
+ self.uids += putter.draw(x / self.scale / scale, y / self.scale / scale, maxy / self.scale / scale, canvas, self.scale * scale)
+ # Im neuen System ist für den Aufgerufenen x,y und maxy entsprechend größer
+ return self.uids
+ def getputter(self, uid):
+ "Nur für oberstes picture; funktioniert nat. auch mit multiputters; 0 für Misserfolg"
+ for putter in self.putters:
+ if uid in putter.uids:
+ return putter
+ return 0
+ def undraw(self, canvas):
+ "NUR FÜR OBERSTES (angezeigtes) PICTURE, ruft alle putter.undraws auf"
+ self.uids = []
+ for putter in self.putters:
+ putter.undraw(canvas)
+
+class circleEx(picelEx):
+ pass
+
+class circle(picel):
+ clickdepth = 2
+ def dumptex(self):
+ if self.bold:
+ sf = '\\thicklines'
+ else:
+ sf = '\\thinlines'
+ sf += '\\circle'
+ if self.filled:
+ sf += '*'
+ sf += '{' + `self.d` + '}'
+ return sf
+ def __init__(self, d, filled, bold = 0):
+ picel.__init__(self)
+ if filled:
+ if d not in POSSIBLEDIAMETERSAS:
+ raise circleEx
+ else:
+ if d not in POSSIBLEDIAMETERS:
+ raise circleEx
+
+ self.d = float(d) # LaTeX erwartet Durchmesser!
+ self.filled = filled
+ self.bold = bold
+ self.changed = 0
+ def dxdy(self, x, y):
+ d = self.d
+ return x - d/2, y - d/2, x + d/2, y + d/2
+ def savestate(self):
+ self.state = self.d, self.filled, self.bold
+ def cancel(self):
+ self.d, self.filled, self.bold = self.state
+ def minfo(self, ox, oy, x, y): # Rechnet mit zweiten Punkt von Benutzeroberfläche die neue Neigung aus
+ dx = x - ox # Relative Position
+ dy = y - oy
+ e = 2 * (dx**2 + dy**2)**0.5 # Entfernung bestimmen
+ self.d = float(diameterer.getd(e, self.filled)) # damit d/2 nicht Durchmesser 1 und 2 ... gleich macht!
+ def changecb(self):
+ self.changed = 1
+ self.tkcallredraw()
+ def change(self, frame, tkcallredraw):
+ self.tkcallredraw = tkcallredraw
+ Label(frame, text = "\circle; \circle*").grid()
+
+ self.tkbold = IntVar()
+ Checkbutton(frame, text = PICELLABELBOLD[LANG], variable = self.tkbold, command = self.changecb).grid()
+ self.tkbold.set(self.bold)
+
+ self.tkfilled = IntVar()
+ Checkbutton(frame, text = CIRCLELABELFILLED[LANG], variable = self.tkfilled, command = self.changecb).grid()
+ self.tkfilled.set(self.filled)
+ def copy(self):
+ return circle(self.d, self.filled, self.bold)
+ def doscale(self, scale):
+ d = self.d * scale
+ self.d = diameterer.getd(d, self.filled)
+ def draw(self, x, y, maxy, canvas, scale = 1):
+ if self.changed:
+ self.bold = self.tkbold.get()
+ self.filled = self.tkfilled.get()
+ self.d = float(diameterer.getd(self.d, self.filled)) # mgl. Durchmesser von gefülltem und ungefülltem Kreis sind verschieden
+ self.changed = 0
+ self.uids = []
+
+ d = self.d * scale
+ d = diameterer.getd(d, self.filled)
+ r = d/2.0
+ boundbox = (fakt * (x - r),
+ fakt * (maxy - y - r),
+ fakt * (x + r),
+ fakt * (maxy - y + r))
+ if self.bold:
+ wi = THICKWIDTH * fakt
+ else:
+ wi = THINWIDTH * fakt
+ self.uids = [canvas.create_oval(boundbox, width = wi)]
+ if self.filled:
+ canvas.itemconfigure(self.uids[0], fill = "BLACK")
+ return self.uids
+
+class lineEx(picelEx):
+ pass
+
+class line(picel):
+ clickdepth = 2
+ def dumptex(self):
+ if self.bold:
+ sf = '\\thicklines'
+ else:
+ sf = '\\thinlines'
+ if self.vec:
+ sf += '\\vector'
+ else:
+ sf += '\\line'
+ sf += `(self.dx, self.dy)` # :-)
+ sf += '{' + `self.len`+ '}'
+ return sf
+ def __init__(self, dx, dy, len, vec, bold = 0):
+ picel.__init__(self)
+ if not (abs(dx), abs(dy)) in POSSIBLEDXDY:
+ raise lineEx
+ self.dx = dx
+ self.dy = dy
+ self.len = len
+ self.vec = vec
+ self.bold = bold
+ self.changed = 0 # für die Konfiguration via change
+ def dxdy(self, x, y):
+ absdxdy = abs(self.dx), abs(self.dy)
+ if absdxdy == (0, 1): # Längen im ersten Quadranten bestimmen
+ dx = 0
+ dy = self.len
+ else:
+ dx = self.len
+ m = absdxdy[1]/float(absdxdy[0])
+ dy = m * dx
+ if self.dx < 0:
+ dx = -dx
+ if self.dy < 0:
+ dy = -dy
+
+ x2 = x + dx # zweite Punkte bilden
+ y2 = y + dy
+
+ return min(x, x2), min(y, y2), max(x, x2), max(y, y2) # richtig geordnete Rückgabe
+ def savestate(self):
+ self.state = self.dx, self.dy, self.len, self.vec, self.bold
+ def cancel(self):
+ self.dx, self.dy, self.len, self.vec, self.bold = self.state
+ def minfo(self, ox, oy, x, y): # Rechnet mit zweiten Punkt von Benutzeroberfläche die neue Neigung aus
+ dx = x - ox # Relative Position
+ dy = y - oy
+ if dx == 0:
+ alpha = math.pi/2
+ else:
+ m = dy/float(dx)
+ alpha = abs(math.atan(m)) # Winkel des zweiten Punktes zum ersten in den Bereich [0; pi/2] pressen.
+ if self.vec:
+ self.dx, self.dy = vecangler.getdxdy(alpha)[1] # nächsten LaTeX-Neigungswinkel errechnen
+ else:
+ self.dx, self.dy = angler.getdxdy(alpha)[1] # nächsten LaTeX-Neigungswinkel errechnen
+
+ if dx < 0:
+ self.dx = -self.dx
+ if dy < 0:
+ self.dy = -self.dy
+ if self.dx == 0:
+ self.len = abs(dy)
+ else:
+ self.len = abs(dx)
+ def vecchangecb(self):
+ if self.dx == 0:
+ self.changecb()
+ return
+ angle = math.atan(abs(self.dy / float(self.dx)))
+ ndx, ndy = vecangler.getdxdy(angle)[1]
+ if self.dx < 0:
+ ndx = -ndx
+ if self.dy < 0:
+ ndy = -ndx
+ self.dx, self.dy = ndx, ndy
+ self.changecb()
+ def changecb(self):
+ self.changed = 1
+ self.tkcallredraw()
+ def change(self, frame, tkcallredraw):
+ self.tkcallredraw = tkcallredraw
+ Label(frame, text = "\line; \vector").grid(columnspan = 2)
+
+ self.tkbold = IntVar()
+ Checkbutton(frame, text = PICELLABELBOLD[LANG], variable = self.tkbold, command = self.changecb).grid(row = 1, columnspan = 2)
+ self.tkbold.set(self.bold)
+
+ self.tkvec = IntVar()
+ Radiobutton(frame, text = LINELABELLINE[LANG], variable = self.tkvec, value = 0, command = self.changecb).grid(row = 2, column = 0)
+ Radiobutton(frame, text = LINELABELVEC[LANG], variable = self.tkvec, value = 1, command = self.vecchangecb).grid(row = 2, column = 1)
+ self.tkvec.set(self.vec)
+
+ def copy(self):
+ return line(self.dx, self.dy, self.len, self.vec, self.bold)
+ def doscale(self, scale):
+ self.len *= scale
+ def draw(self, x, y, maxy, canvas, scale = 1):
+ len = self.len * scale
+ if self.changed:
+ self.vec = self.tkvec.get()
+ self.bold = self.tkbold.get()
+ self.changed = 0
+ self.uids = []
+ # Koordinaten des zweiten Punktes bestimmen
+ if (abs(self.dx), abs(self.dy)) == (0, 1): # Vertikale Linie
+ x2 = x
+ ylen = self.dy/(abs(self.dy)) * len # Vorzeichenbehaftet!
+ y2 = y + ylen
+ else: # Alle anderen Liniensorten
+ # aus x-Projektion der Länge und Neigung den y-Anteil ausrechnen
+ m = self.dy/float(self.dx)
+ xlen = self.dx/abs(self.dx) * len # LaTeX-Länge + Vorzeichen -> DeltaX
+ ylen = m * xlen
+ x2 = x + xlen
+ y2 = y + ylen
+ arrowshape = (ARROWSHAPE[0] * scale * fakt, ARROWSHAPE[1] * scale * fakt, ARROWSHAPE[2] * scale * fakt)
+ if self.vec: # Pfeil?
+ ar = LAST
+ else:
+ ar = NONE
+ if self.bold:
+ wi = THICKWIDTH * fakt
+ else:
+ wi = THINWIDTH * fakt
+
+ self.uids = [canvas.create_line(fakt * x, fakt * (maxy - y), fakt * x2, fakt * (maxy - y2), width = wi, arrow = ar, arrowshape = arrowshape)]
+ return self.uids
+
+class ovalEx(picelEx):
+ pass
+
+class oval(picel):
+ clickdepth = 2
+ BUTTEXTS = (OVALALL[LANG],
+ OVALT[LANG],
+ OVALL[LANG],
+ OVALR[LANG],
+ OVALB[LANG],
+ OVALTR[LANG],
+ OVALTL[LANG],
+ OVALBL[LANG],
+ OVALBR[LANG])
+ def dumptex(self):
+ if self.bold:
+ sf = '\\thicklines'
+ else:
+ sf = '\\thinlines'
+
+ selstr = ('',
+ '[t]',
+ '[l]',
+ '[r]',
+ '[b]',
+ '[tr]',
+ '[tl]',
+ '[bl]',
+ '[br]')[self.at]
+
+ sf += '\\oval' + `(self.dx, self.dy)` + selstr
+
+ return sf
+ def atlrbTrTlBlBr2selector(self, atlrbTrTlBlBr):
+ if atlrbTrTlBlBr == 0: # A
+ return 1, 1, 1, 1
+ elif atlrbTrTlBlBr == 1: # T
+ return 1, 1, 0, 0
+ elif atlrbTrTlBlBr == 2: # L
+ return 0, 1, 1, 0
+ elif atlrbTrTlBlBr == 3: # R
+ return 1, 0, 0, 1
+ elif atlrbTrTlBlBr == 4: # B
+ return 0, 0, 1, 1
+ elif atlrbTrTlBlBr == 5: # TR
+ return 1, 0, 0, 0
+ elif atlrbTrTlBlBr == 6: # TL
+ return 0, 1, 0, 0
+ elif atlrbTrTlBlBr == 7: # BL
+ return 0, 0, 1, 0
+ elif atlrbTrTlBlBr == 8: # BR
+ return 0, 0, 0, 1
+ def __init__(self, dx, dy, atlrbTrTlBlBr = 0, bold = 0):
+ # atlrb - alles = 0, top = 1, left = 2 ...
+ if atlrbTrTlBlBr not in range(9):
+ raise ovalEx
+ picel.__init__(self)
+ self.dx = dx
+ self.dy = dy
+ self.selector = self.atlrbTrTlBlBr2selector(atlrbTrTlBlBr)
+ self.at = atlrbTrTlBlBr
+ self.bold = bold
+ self.changed = 0
+ def dxdy(self, x, y):
+ dxh = self.dx / 2.0
+ dyh = self.dy / 2.0
+ if self.at in [4, 8, 5]: #[R, BR, TR]:
+ x1 = x
+ else:
+ x1 = x - dxh
+ if self.at in [1, 6, 5]: #[T, TL, TR]:
+ y1 = y
+ else:
+ y1 = y - dyh
+
+ if self.at in [3, 6, 7]: #[L, TL, BL]:
+ x2 = x
+ else:
+ x2 = x + dxh
+
+ if self.at in [2, 7, 8]: #[B, BL, BR]:
+ y2 = y
+ else:
+ y2 = y + dyh
+ return x1, y1, x2, y2
+ def savestate(self):
+ self.state = self.dx, self.dy, self.selector, self.at, self.bold
+ def cancel(self):
+ self.dx, self.dy, self.selector, self.at, self.bold = self.state
+ def minfo(self, ox, oy, x, y):
+ self.dx = abs(ox - x) * 2
+ self.dy = abs(oy - y) * 2
+ def changecb(self):
+ self.changed = 1
+ self.tkcallredraw()
+ def change(self, frame, tkcallredraw):
+ self.tkcallredraw = tkcallredraw
+ Label(frame, text = "\oval").pack()
+
+ self.tkbold = IntVar()
+ Checkbutton(frame, text = PICELLABELBOLD[LANG], variable = self.tkbold, command = self.changecb).pack()
+ self.tkbold.set(self.bold)
+
+ self.tksel = IntVar()
+ for z in range(9):
+ Radiobutton(frame, text = self.BUTTEXTS[z], variable = self.tksel, value = z, command = self.changecb).pack(anchor = W)
+ self.tksel.set(self.at)
+ def copy(self):
+ return oval(self.dx, self.dy, self.at, self.bold)
+ def doscale(self, scale):
+ self.dx *= scale
+ self.dy *= scale
+ def draw(self, x, y, maxy, canvas, scale = 1):
+ dx = self.dx * scale
+ dy = self.dy * scale
+ if self.changed:
+ self.bold = self.tkbold.get()
+ self.at = self.tksel.get()
+ self.selector = self.atlrbTrTlBlBr2selector(self.at)
+ self.changed = 0
+ self.uids = []
+ # Kürzere Seite bestimmen
+ if dx < dy:
+ lmin = dx
+ else:
+ lmin = dy
+ d = 0 # Daraus kann LaTeX machen was es will. Wohl nicht viel.
+ # Radius bestimmen
+ for i in range(len(POSSIBLEDIAMETERS) - 1, -1, -1):
+ if POSSIBLEDIAMETERS[i] <= lmin:
+ d = POSSIBLEDIAMETERS[i]
+ break
+ d = float(d)
+ # Eckpunkte bestimmen
+ mx = x
+ my = y
+ x -= dx/2
+ y -= dy/2
+ x2 = x + dx
+ y2 = y + dy
+
+ # Kreisbögen zeichnen
+ if self.bold:
+ wi = THICKWIDTH * fakt
+ else:
+ wi = THINWIDTH * fakt
+
+ # rechts oben
+ if self.selector[0]:
+ self.uids.append(
+ canvas.create_line(
+ fakt * mx, fakt * (maxy - y2), fakt * (x2 - d/2), fakt * (maxy - y2), width = wi))
+ self.uids.append(
+ canvas.create_line(
+ fakt * x2, fakt * (maxy - my), fakt * x2, fakt * (maxy - (y2 - d/2)), width = wi))
+ bbox = fakt * (x2 - d), fakt * (maxy - (y2 - d)), fakt * x2, fakt * (maxy - y2)
+ self.uids.append(
+ canvas.create_arc(bbox, start = 0, extent = 90, style = ARC, width = wi))
+ # Links oben
+ if self.selector[1]:
+ self.uids.append(
+ canvas.create_line(
+ fakt * (x + d/2), fakt * (maxy - y2), fakt * mx, fakt * (maxy - y2), width = wi))
+ self.uids.append(
+ canvas.create_line(
+ fakt * x, fakt * (maxy - my), fakt * x, fakt * (maxy - (y2 - d/2)), width = wi))
+ bbox = fakt * x, fakt * (maxy - (y2 - d)), fakt * (x + d), fakt * (maxy - y2)
+ self.uids.append(
+ canvas.create_arc(bbox, start = 90, extent = 90, style = ARC, width = wi))
+ # Links unten
+ if self.selector[2]:
+ self.uids.append(
+ canvas.create_line(
+ fakt * x, fakt * (maxy - (y + d/2)), fakt * x, fakt * (maxy - my), width = wi))
+ self.uids.append(
+ canvas.create_line(
+ fakt * (x + d/2), fakt * (maxy - y), fakt * mx, fakt * (maxy - y), width = wi))
+ bbox = fakt * x, fakt * (maxy - y), fakt * (x + d), fakt * (maxy - (y + d))
+ self.uids.append(
+ canvas.create_arc(bbox, start = 180, extent = 90, style = ARC, width = wi))
+ # Rechts unten
+ if self.selector[3]:
+ self.uids.append(
+ canvas.create_line(
+ fakt * mx, fakt * (maxy - y), fakt * (x2 - d/2), fakt * (maxy - y), width = wi))
+ self.uids.append(
+ canvas.create_line(
+ fakt * x2, fakt * (maxy - (y + d/2)), fakt * x2, fakt * (maxy - my), width = wi))
+ bbox = fakt * (x2 - d), fakt * (maxy - y), fakt * x2, fakt * (maxy - (y + d))
+ self.uids.append(
+ canvas.create_arc(bbox, start = 270, extent = 90, style = ARC, width = wi))
+ return self.uids
+
+class bezierEx(picelEx):
+ pass
+
+class bezier(picel):
+ clickdepth = 3
+ def dumptex(self):
+ if self.bold:
+ sf = '\\thicklines'
+ else:
+ sf = '\\thinlines'
+ sf += '\\qbezier' + `(self.xa, self.ya)` + `(self.xb, self.yb)` + `(self.xc, self.yc)`
+ return sf
+ def __init__(self, xa, ya, xb, yb, xc, yc, bold = 0):
+ picel.__init__(self)
+ self.xa = xa
+ self.ya = ya
+ self.xb = xb
+ self.yb = yb
+ self.xc = xc
+ self.yc = yc
+ self.bold = bold
+ self.changed = 0
+ def dxdy(self, x, y):
+ x1 = min(self.xa, self.xb, self.xc)
+ x2 = max(self.xa, self.xb, self.xc)
+ y1 = min(self.ya, self.yb, self.yc)
+ y2 = max(self.ya, self.yb, self.yc)
+ return x1 + x, y1 + y, x2 + x, y2 + y
+ def copy(self):
+ return bezier(self.xa, self.ya, self.xb, self.yb, self.xc, self.yc, self.bold)
+ def savestate(self):
+ self.state = self.xa, self.ya, self.xb, self.yb, self.xc, self.yc
+ def cancel(self):
+ self.xa, self.ya, self.xb, self.yb, self.xc, self.yc = self.state
+ def minfo(self, ox, oy, x, y):
+ dx = x - ox
+ dy = y - oy
+ self.xc = dx
+ self.yc = dy
+ def minfo2(self, ox, oy, x, y):
+ dx = x - ox
+ dy = y - oy
+ self.xb = dx
+ self.yb = dy
+ def changecb(self):
+ self.changed = 1
+ self.tkcallredraw()
+ def change(self, frame, tkcallredraw):
+ self.tkcallredraw = tkcallredraw
+ Label(frame, text = "\qbezier").grid()
+
+ self.tkbold = IntVar()
+ Checkbutton(frame, text = PICELLABELBOLD[LANG], variable = self.tkbold, command = self.changecb).grid()
+ self.tkbold.set(self.bold)
+ def doscale(self, scale):
+ self.xa *= scale
+ self.ya *= scale
+ self.xb *= scale
+ self.yb *= scale
+ self.xc *= scale
+ self.yc *= scale
+ def draw(self, x, y, maxy, canvas, scale = 1):
+ xa = self.xa * scale
+ ya = self.ya * scale
+ xb = self.xb * scale
+ yb = self.yb * scale
+ xc = self.xc * scale
+ yc = self.yc * scale
+ if self.changed:
+ self.bold = self.tkbold.get()
+ self.changed = 0
+ self.uids = []
+ if self.bold:
+ wi = THICKWIDTH * fakt
+ else:
+ wi = THINWIDTH * fakt
+ uid = canvas.create_line(fakt * (x + xa),
+ fakt * (maxy - (y + ya)),
+ fakt * (x + xb),
+ fakt * (maxy - (y + yb)),
+ fakt * (x + xc),
+ fakt * (maxy - (y + yc)),
+ smooth = 1,
+ width = wi
+ )
+ self.uids = [uid]
+ return self.uids
+
+class simpletext(picel):
+ # Einfacher Textstring
+ clickdepth = 1
+ def dumptex(self):
+ return self.text
+ def __init__(self, text):
+ picel.__init__(self)
+ self.text = text
+ def dxdy(self, x, y): # Keine Ahnung, wie groß der Text wird, ich müsste ja LaTeX neu schreiben!
+ return x, y, x, y
+ def copy(self):
+ return simpletext(self.text)
+ def changecb(self, a1, a2, a3):
+ self.text = self.tktext.get() # Muss eine Zeichenkette sein
+ def change(self, frame, tkcallredraw):
+ self.tkcallredraw = tkcallredraw
+ Label(frame, text = "<einfacher Text>").grid()
+
+ self.tktext = StringVar()
+ Entry(frame, textvariable = self.tktext).grid()
+ self.tktext.set(self.text)
+ self.tktext.trace("w", self.changecb)
+ def doscale(self, scale):
+ pass
+ def draw(self, x, y, maxy, canvas, scale = 1):
+ self.uids = []
+ uid = canvas.create_text(fakt * x, fakt * (maxy - y), anchor = S + W, text = '*TEXT*')
+
+ self.uids = [uid]
+ return self.uids
+
+class textboxEx(picelEx):
+ pass
+
+class textbox(picel):
+ # VORSICHT: textbox erlaubt negative dx, dy!
+ clickdepth = 2
+ def dumptex(self, x, y, dx, dy, n): # und daher wird dieser hier nur mit allen Informationen von multiputer aufgefordert, dessen Job zu übernehmen.
+ sdx = self.dx
+ sdy = self.dy
+ if sdx < 0:
+ sdx = -sdx
+ x -= sdx
+ if sdy < 0:
+ sdy = -sdy
+ y -= sdy
+
+ if n != 1:
+ sf = '\\multiput' + `(x, y)` + `(dx, dy)` + '{' + `n` + '}{'
+ else:
+ sf = '\\put' + `(x, y)` + '{'
+
+ if self.bold:
+ sf += '\\thicklines'
+ else:
+ sf += '\\thinlines'
+ # Auswahl des Kommandos
+ if self.dash < 0:
+ sf += '\\makebox'
+ elif self.dash == 0:
+ sf += '\\framebox'
+ elif self.dash > 0:
+ sf += '\\dashbox{' + `self.dash` + '}'
+
+ sf += `(sdx, sdy)`
+
+ # Poitionierungsangabe
+ if self.lmr != 1 or self.bmt != 1:
+ sf += '['
+ sf += ['l', '', 'r'][self.lmr]
+ sf += ['b', '', 't'][self.bmt]
+ sf += ']'
+ sf += '{' + self.text
+
+ sf += '}}' # von der box und vom putter
+
+ return sf
+ def __init__(self, dx, dy, lmr, bmt, dash, text, bold = 0):
+ "lmr -> 0: l, 1: m, 2: r ...; dash = 0 -> \framebox, sonst Strichlänge; negativ -> kein Rahmen"
+ self.lmr = lmr
+ self.bmt = bmt
+ if not (lmr in range(3) and bmt in range(3)):
+ raise textboxEx
+ picel.__init__(self)
+ self.text = text
+ self.dx = dx
+ self.dy = dy
+ self.dash = dash
+ self.bold = bold
+ self.changed = 0
+ def copy(self):
+ return textbox(self.dx, self.dy, self.lmr, self.bmt, self.dash, self.text, self.bold)
+ def dxdy(self, x, y):
+ if self.dx < 0:
+ x1 = x + self.dx
+ x2 = x
+ else:
+ x1 = x
+ x2 = x + self.dx
+ if self.dy < 0:
+ y1 = y + self.dy
+ y2 = y
+ else:
+ y1 = y
+ y2 = y + self.dy
+ return x1, y1, x2, y2
+ def savestate(self):
+ self.state = self.lmr, self.bmt, self.text, self.dx, self.dy, self.dash, self.bold
+ def cancel(self):
+ self.lmr, self.bmt, self.text, self.dx, self.dy, self.dash, self.bold = self.state
+ def minfo(self, ox, oy, x, y):
+ self.dx = x - ox
+ self.dy = y - oy
+ def changecb2(self, a1, a2, a3):
+ self.text = self.tktext.get()
+ self.changed = 1
+ self.tkcallredraw()
+ def changecb(self):
+ self.changed = 1
+ self.tkcallredraw()
+ def changecbworkaround(self, event):
+ self.changecb()
+ def change(self, frame, tkcallredraw):
+ self.tkcallredraw = tkcallredraw
+ Label(frame, text = "\dashbox; \framebox; \makebox").pack()
+
+ # Fett
+ self.tkbold = IntVar()
+ Checkbutton(frame, text = PICELLABELBOLD[LANG], variable = self.tkbold, command = self.changecb).pack()
+ self.tkbold.set(self.bold)
+
+ # Text
+ self.tktext = StringVar()
+ textframe = Frame(frame, borderwidth = 1, relief = RAISED)
+ textframe.pack(fill = BOTH, expand = 1)
+ Label(textframe, text = PICELLABELTEXT[LANG]).pack(side = LEFT)
+ Entry(textframe, textvariable = self.tktext).pack(side = RIGHT, fill = X, expand = 1)
+ self.tktext.set(self.text)
+ self.tktext.trace("w", self.changecb2)
+
+ # Rahmenart
+
+ self.tkstyle = IntVar()
+ borderframe = Frame(frame, borderwidth = 1, relief = RAISED)
+ borderframe.pack(fill = BOTH, expand = 1)
+ Label(borderframe, text = TEXTBOXLABELBORDER[LANG]).grid(row = 0, column = 0, columnspan = 3)
+ Radiobutton(borderframe, text = TEXTBOXLABELNOBORDER[LANG], variable = self.tkstyle, value = -1, command = self.changecb).grid(row = 1, column = 0)
+ Radiobutton(borderframe, text = TEXTBOXLABELFULLBORDER[LANG], variable = self.tkstyle, value = 0, command = self.changecb).grid(row = 1, column = 1)
+ Radiobutton(borderframe, text = TEXTBOXLABELDASHEDBORDER[LANG], variable = self.tkstyle, value = 1, command = self.changecb).grid(row = 1, column = 2)
+ if self.dash < 0:
+ self.tkstyle.set(-1)
+ elif self.dash == 0:
+ self.tkstyle.set(0)
+ else:
+ self.tkstyle.set(1)
+
+ self.tkdashlen = DoubleVar()
+ borderframe2 = Frame(borderframe)
+ borderframe2.grid(sticky = N+E+S+W, columnspan = 3)
+ Label(borderframe2, text = TEXTBOXLABELDASHLEN[LANG]).pack(side = LEFT)
+ EDashLen = Entry(borderframe2, textvariable = self.tkdashlen)
+ EDashLen.pack(side = RIGHT, fill = X, expand = 1)
+ EDashLen.bind('<Return>', self.changecbworkaround)
+ if self.tkstyle.get() == 1: # Inhalt des Strichlängenfeldes bestimmen
+ self.tkdashlen.set(self.dash)
+ else:
+ self.tkdashlen.set(DEFAULTDASHLEN)
+
+ # Position
+ self.tkpos = IntVar()
+ posframe = Frame(frame, borderwidth = 1, relief = RAISED)
+ posframe.pack(fill = BOTH, expand = 1)
+ Label(posframe, text = TEXTBOXLABELPOS[LANG]).grid(row = 0, columnspan = 3)
+ Radiobutton(posframe, variable = self.tkpos, value = 00, command = self.changecb).grid(row = 3, column = 0)
+ Radiobutton(posframe, variable = self.tkpos, value = 01, command = self.changecb).grid(row = 3, column = 1)
+ Radiobutton(posframe, variable = self.tkpos, value = 02, command = self.changecb).grid(row = 3, column = 2)
+
+ Radiobutton(posframe, variable = self.tkpos, value = 10, command = self.changecb).grid(row = 2, column = 0)
+ Radiobutton(posframe, variable = self.tkpos, value = 11, command = self.changecb).grid(row = 2, column = 1)
+ Radiobutton(posframe, variable = self.tkpos, value = 12, command = self.changecb).grid(row = 2, column = 2)
+
+ Radiobutton(posframe, variable = self.tkpos, value = 20, command = self.changecb).grid(row = 1, column = 0)
+ Radiobutton(posframe, variable = self.tkpos, value = 21, command = self.changecb).grid(row = 1, column = 1)
+ Radiobutton(posframe, variable = self.tkpos, value = 22, command = self.changecb).grid(row = 1, column = 2)
+ self.tkpos.set(self.bmt * 10 + self.lmr)
+ # bmt, lmr -> init
+ # Beide zusammen werden als value des Knopfes gesichert, indem der vertikale Anteil mit 10
+ # multipliziert eingeht.
+ def dashline(self, x1, x2, y, dash, h, wi, canvas): # Hilfsfunktion
+ uids = []
+ if x2 < x1: # ggf. Parameter vertauschen
+ dummy = x2
+ x2 = x1
+ x1 = dummy
+
+ anz = (x2 - x1) / float(dash) # Anzahl der kompletten Striche
+ rest = (anz - int(anz)) * dash # Länge des Reststückes
+ z = -1
+ for z in range(anz):
+ if z % 2 == 0: # Nur die Hälfte der Striche anzeigen
+ if h:
+ newuid = canvas.create_line(x1 + z * dash, y, x1 + (z + 1) * dash, y, width = wi)
+ else:
+ newuid = canvas.create_line(y, x1 + z * dash, y, x1 + (z + 1) * dash, width = wi)
+ uids.append(newuid)
+ z += 1
+ if z % 2 == 0:
+ if h:
+ newuid = canvas.create_line(x1 + z * dash, y, x2, y, width = wi)
+ else:
+ newuid = canvas.create_line(y, x1 + z * dash, y, x2, width = wi)
+ uids.append(newuid)
+ return uids
+ def drawdash(self, x, y, maxy, canvas, scale = 1):
+ "Hilfsfunktion für .draw: alle \dahslines"
+ dx = self.dx * scale
+ dy = self.dy * scale
+ dash = self.dash * scale
+ self.uids = []
+ if self.bold:
+ wi = THICKWIDTH * fakt
+ else:
+ wi = THINWIDTH * fakt
+ # Horizontale Linien (h = 1)
+ self.uids += \
+ self.dashline(fakt * x, fakt * (x + dx), fakt * (maxy - y), fakt * dash, 1, wi, canvas)
+ self.uids += \
+ self.dashline(fakt * x, fakt * (x + dx), fakt * (maxy - (y + dy)), fakt * dash, 1, wi, canvas)
+ # Vertikale Linien (h = 0)
+ self.uids += \
+ self.dashline(fakt * (maxy - y), fakt * (maxy - (y + dy)), fakt * x, fakt * dash, 0, wi, canvas)
+ self.uids += \
+ self.dashline(fakt * (maxy - y), fakt * (maxy - (y + dy)), fakt * (x + dx), fakt * dash, 0, wi, canvas)
+ def drawfull(self, x, y, maxy, canvas, scale = 1):
+ "Hilfsfunktion für .draw: alle \makebox sowie \framebox"
+ dx = self.dx * scale
+ dy = self.dy * scale
+ self.uids = []
+ if self.bold:
+ wi = THICKWIDTH * fakt
+ else:
+ wi = THINWIDTH * fakt
+ # Horizontale Linien
+ if self.dash < 0:
+ col = MAKEBOXCOL
+ else:
+ col = "black"
+ self.uids.append(
+ canvas.create_line(fakt * x, fakt * (maxy - y), fakt * (x + dx), fakt * (maxy - y), width = wi, fill = col))
+ self.uids.append(
+ canvas.create_line(fakt * x, fakt * (maxy - (y + dy)), fakt * (x + dx), fakt * (maxy - (y + dy)), width = wi, fill = col))
+ # Vertikale Linien
+ self.uids.append(
+ canvas.create_line(fakt * x, fakt * (maxy - y), fakt * x, fakt * (maxy - (y + dy)), width = wi, fill = col))
+ self.uids.append(
+ canvas.create_line(fakt * (x + dx), fakt * (maxy - y), fakt * (x + dx), fakt * (maxy - (y + dy)), width = wi, fill = col))
+ def doscale(self, scale):
+ self.dx *= scale
+ self.dy *= scale
+ if self.dash > 0:
+ self.dash *= scale
+ def draw(self, x, y, maxy, canvas, scale = 1):
+ if self.changed:
+ self.bold = self.tkbold.get()
+ val = self.tkpos.get()
+ self.bmt = val / 10
+ self.lmr = val % 10
+ # Siehe Kommentar in change
+ dashstyle = self.tkstyle.get()
+ if dashstyle == -1: # Ohne Rahmen
+ self.dash = -1
+ elif dashstyle == 0: # Durchgezogen
+ self.dash = 0
+ else:
+ try:
+ if self.tkdashlen.get() <= 0:
+ raise ValueError
+ self.dash = self.tkdashlen.get() # gestrichelt
+ except:
+ self.tkdashlen.set(self.dash)
+ self.changed = 0
+ # Rand zeichnen
+ if self.dash <= 0:
+ self.drawfull(x, y, maxy, canvas, scale)
+ else:
+ self.drawdash(x, y, maxy, canvas, scale)
+ dx = self.dx * scale
+ dy = self.dy * scale
+ # Text zeichnen
+ an = ''
+ xpos = x + dx/2
+ ypos = y + dy/2
+ if self.text != '':
+ if self.bmt == 0:
+ an += S
+ if dy < 0:
+ ypos = y + dy
+ else:
+ ypos = y
+ elif self.bmt == 2:
+ an += N
+ if dy < 0:
+ ypos = y
+ else:
+ ypos = y + dy
+ if self.lmr == 0:
+ an += W
+ if dx < 0:
+ xpos = x + dx
+ else:
+ xpos = x
+ elif self.lmr == 2:
+ an += E
+ if dx < 0:
+ xpos = x
+ else:
+ xpos = x + dx
+ if an == '':
+ an = CENTER
+ self.uids.append(
+ canvas.create_text(fakt * xpos, fakt * (maxy - ypos), text = "*TEXT*", anchor = an))
+ return self.uids
+
+class shortstackEx(picelEx):
+ pass
+
+class shortstack(picel):
+ clickdepth = 1
+ def dumptex(self):
+ sf = '\\shortstack'
+ sf += ['[l]{', '{', '[r]{'][self.lrc]
+ sf += self.text + '}'
+ return sf
+ def __init__(self, lrc, text):
+ if lrc not in range(3):
+ raise shortstackEx
+ picel.__init__(self)
+ self.text = text
+ self.lrc = lrc
+ self.changed = 0
+ def dxdy(self, x, y):
+ return x, y, x, y # Keine Ahnung betreffend die Größe von self.text
+ def copy(self):
+ return shortstack(self.lrc, self.text)
+ def changecb2(self, a1, a2, a3):
+ self.text = self.tktext.get()
+ def changecb(self):
+ self.changed = 1
+ self.tkcallredraw()
+ def change(self, frame, tkcallredraw):
+ self.tkcallredraw = tkcallredraw
+ Label(frame, text = "\\shortstack").grid(columnspan = 2)
+ self.tktext = StringVar()
+ Label(frame, text = PICELLABELTEXT[LANG]).grid(row = 1, column = 0)
+ Entry(frame, textvariable = self.tktext).grid(row = 1, column = 1)
+ self.tktext.set(self.text)
+ self.tktext.trace("w", self.changecb2)
+
+ self.tklrc = IntVar()
+ Radiobutton(frame, text = SHORTSTACKLABELLEFT[LANG], variable = self.tklrc, value = 0, command = self.changecb).grid(sticky = W)
+ Radiobutton(frame, text = SHORTSTACKLABELCENTERED[LANG], variable = self.tklrc, value = 1, command = self.changecb).grid(sticky = W)
+ Radiobutton(frame, text = SHORTSTACKLABELRIGHT[LANG], variable = self.tklrc, value = 2, command = self.changecb).grid(sticky = W)
+ self.tklrc.set(self.lrc)
+ def doscale(self, scale):
+ pass
+ def draw(self, x, y, maxy, canvas, scale = 1):
+ if self.changed:
+ self.lrc = self.tklrc.get()
+ self.changed = 0
+ self.uids = []
+ if self.lrc == 0:
+ disptext = SHORTSTACKSHOWLEFT[LANG]
+ elif self.lrc == 1:
+ disptext = SHORTSTACKSHOWCENTERED[LANG]
+ elif self.lrc == 2:
+ disptext = SHORTSTACKSHOWRIGHT[LANG]
+ self.uids.append(
+ canvas.create_text(fakt * x, fakt * (maxy - y), text = disptext, anchor = S + W))
+ return self.uids
+
+class sizechanger: # Ändert dazu noch den Namen
+ def __init__(self, root, sizex, sizey, name, names, changedcb):
+ # Alte Werte; names: Liste der benutzten Namen; changedcb(x, y, name)
+ self.sizex = sizex
+ self.sizey = sizey
+ self.name = name
+ self.names = names
+ self.changedcb = changedcb
+
+ # Fenster erstellen
+ self.tl = Toplevel(root)
+ self.tl.title = 'Abmessungen'
+
+ self.tkx = DoubleVar()
+ self.tky = DoubleVar()
+ self.tkname = StringVar()
+ self.tkx.set(sizex)
+ self.tky.set(sizey)
+ self.tkname.set(name)
+ Label(self.tl, text = SIZECHANGEX[LANG]).grid(row = 0, column = 0)
+ Label(self.tl, text = SIZECHANGEY[LANG]).grid(row = 1, column = 0)
+ Label(self.tl, text = SIZECHANGENAME[LANG]).grid(row = 2, column = 0)
+ Entry(self.tl, textvariable = self.tkx).grid(row = 0, column = 1, sticky = E + W)
+ Entry(self.tl, textvariable = self.tky).grid(row = 1, column = 1, sticky = E + W)
+ Entry(self.tl, textvariable = self.tkname).grid(row = 2, column = 1, sticky = E + W)
+ Button(self.tl, command = self.apply, text = SIZECHANGEOK[LANG], state = ACTIVE).grid(row = 3, column = 0, columnspan = 2)
+ self.tl.bind("<Return>", self.apply)
+ def apply(self, event = None):
+ xgot, ygot, namegot = self.tkx.get(), self.tky.get(), self.tkname.get()
+ if xgot < 0:
+ xgot = self.sizex
+ if ygot < 0:
+ ygot = self.sizey
+ if namegot in self.names:
+ namegot = self.name
+ self.changedcb(xgot, ygot, namegot)
+ self.tl.destroy()
+
+class bb(picel):
+ "Dicker Strich in Funktion eines ausgefüllten Rechtecks; Skalierungsfehler: Breite wird nie angepasst; richtige Darstellung (hoffentlich)"
+ clickdepth = 2
+ def dumptex(self, x, y, dx, dy, n): # Braucht auch die Informationen vom Putter, denn putter kommt links in der Mitte.
+ py = y + self.dy / 2.0
+ if self.dx < 0:
+ px = self.dx + x
+ else:
+ px = x
+ len = abs(self.dx)
+
+ thickness = abs(self.dy)
+
+ if n != 1:
+ sf = '\\multiput' + `(px, py)` + `(dx, dy)` + '{' + `n` + '}{'
+ else:
+ sf = '\\put' + `(px, py)` + '{'
+
+ sf += '\\linethickness{' + `thickness`+ '\unitlength}'
+ sf += '\\line(1, 0){' + `len` + '} }'
+
+ return sf
+ def __init__(self, dx, dy):
+ picel.__init__(self)
+ self.dx = dx
+ self.dy = dy
+ def dxdy(self, x, y):
+ if self.dx < 0:
+ x1 = x + self.dx
+ x2 = x
+ else:
+ x1 = x
+ x2 = x + self.dx
+ if self.dy < 0:
+ y1 = y + self.dy
+ y2 = y
+ else:
+ y1 = y
+ y2 = y + self.dy
+ return x1, y1, x2, y2
+ def savestate(self):
+ self.state = self.dx, self.dy
+ def cancel(self):
+ self.dx, self.dy = self.state
+ def minfo(self, ox, oy, x, y):
+ self.dx = x - ox # Relative Position
+ self.dy = y - oy
+ def change(self, frame, tkcallredraw):
+ Label(frame, text = "\\textwidth\\line").pack()
+ def copy(self):
+ return bb(self.dx, self.dy)
+ def doscale(self, scale):
+ self.dx *= scale
+ self.dy *= scale
+ def draw(self, x, y, maxy, canvas, scale = 1):
+ boundbox = (fakt * (x),
+ fakt * (maxy - y),
+ fakt * (x + self.dx * scale),
+ fakt * (maxy - (y + self.dy * scale)))
+ return [canvas.create_rectangle(boundbox, fill = "BLACK")]
+
+class objignorestatus:
+ def status(sf):
+ pass
+
+class tkfiledummy: # simuliert die gebrauchte Funktionalität
+ def __init__(self):
+ self.size = (10, 10)
+ def resize(self, newsizetup):
+ self.size = newsizetup
+
+class eps(picel):
+ clickdepth = 2
+ def dumptex(self):
+ sf = "\includegraphics[width = " + `self.dx` + '\unitlength, height = ' + `self.dy` + "\unitlength]{" + self.filename + "}"
+ return sf
+ def loadfile(self, filename, statusobj):
+ print "loadfile called"
+ self.filename = filename
+ try:
+ self.tkfile = Image.open(filename)
+ except:
+ statusobj.status(EPSCANNOTOPEN[LANG])
+ self.tkfile = tkfiledummy()
+ return 0
+ if self.tkfile.format != 'EPS':
+ statusobj.status(EPSNOEPS[LANG])
+ self.tkfile = tkfiledummy()
+ return 0
+ return 1
+ def __init__(self, dx = 0, dy = 0, keepaspect = 1):
+ picel.__init__(self)
+ self.tkfile = tkfiledummy() # NOCH NICHT BENUTZEN!!! Loadfile aufrufen!
+ self.dx = dx
+ self.dy = dy
+ self.keepaspect = keepaspect
+ self.tkimagelist = [] # Photoimages brauchen zusätzliche Referenz. Bei putter.undraw() wird imagelist geleert.
+ self.changed = 0
+ def dxdy(self, x, y):
+ return x, y, x + self.dx, y + self.dy
+ def savestate(self):
+ self.state = self.tkfile, self.dx, self.dy
+ def cancel(self):
+ self.tkfile, self.dx, self.dy = self.state
+ def minfo(self, ox, oy, x, y):
+ aspect = self.tkfile.size[0] / float(self.tkfile.size[1])
+ dx = x - ox # Relative Position
+ dy = y - oy
+ if dx < 0:
+ dx = 0
+ if dy < 0:
+ dy = 0
+ if self.keepaspect: # Verhältnis Länge/Höhe beibehalten
+ dx = aspect * dy
+ self.dx, self.dy = dx, dy
+ def changecb(self):
+ self.changed = 1
+ self.tkcallredraw()
+ def change(self, frame, tkcallredraw):
+ self.tkcallredraw = tkcallredraw
+ Label(frame, text = "\epsfig").pack()
+ Label(frame, text = EPSINSERTNOTE[LANG]).pack()
+ self.tkkeepaspect = IntVar()
+ self.tkkeepaspect.set(self.keepaspect)
+ Checkbutton(frame, text = EPSASPECT[LANG], variable = self.tkkeepaspect, command = self.changecb).pack()
+ def copy(self):
+ neweps = eps(self.dx, self.dy, self.keepaspect)
+ neweps.loadfile(self.filename, objignorestatus())
+ return neweps
+ def doscale(self, scale):
+ self.dx *= scale
+ self.dy *= scale
+ def undrawhook(self):
+ self.tkimagelist = []
+ def draw(self, x, y, maxy, canvas, scale = 1):
+ if self.changed:
+ self.keepaspect = self.tkkeepaspect.get()
+ if self.keepaspect: # verzerrtes Bild richten, wenn Benutzer ausgeschalteten aspect wieder eingeschaltet hat.
+ self.minfo(0, 0, self.dx, self.dy)
+ width = self.dx * fakt * scale
+ height = self.dy * fakt * scale
+ if self.tkfile.__class__ != tkfiledummy:
+ im = ImageTk.PhotoImage(image = self.tkfile.resize((width, height)) )
+ self.tkimagelist.append(im)
+ uid = canvas.create_image(fakt * x + width / 2, fakt * maxy - (fakt * y + height / 2), image = im)
+ return [uid]
+ else:
+ boundbox = (fakt * (x),
+ fakt * (maxy - y),
+ fakt * (x + self.dx * scale),
+ fakt * (maxy - (y + self.dy * scale)))
+ return [canvas.create_rectangle(boundbox),
+ canvas.create_line(boundbox)]