PyXR

c:\python24\lib\lib-tk \ turtle.py



0001 # LogoMation-like turtle graphics
0002 
0003 from math import * # Also for export
0004 import Tkinter
0005 
0006 class Error(Exception):
0007     pass
0008 
0009 class RawPen:
0010 
0011     def __init__(self, canvas):
0012         self._canvas = canvas
0013         self._items = []
0014         self._tracing = 1
0015         self._arrow = 0
0016         self.degrees()
0017         self.reset()
0018 
0019     def degrees(self, fullcircle=360.0):
0020         self._fullcircle = fullcircle
0021         self._invradian = pi / (fullcircle * 0.5)
0022 
0023     def radians(self):
0024         self.degrees(2.0*pi)
0025 
0026     def reset(self):
0027         canvas = self._canvas
0028         self._canvas.update()
0029         width = canvas.winfo_width()
0030         height = canvas.winfo_height()
0031         if width <= 1:
0032             width = canvas['width']
0033         if height <= 1:
0034             height = canvas['height']
0035         self._origin = float(width)/2.0, float(height)/2.0
0036         self._position = self._origin
0037         self._angle = 0.0
0038         self._drawing = 1
0039         self._width = 1
0040         self._color = "black"
0041         self._filling = 0
0042         self._path = []
0043         self._tofill = []
0044         self.clear()
0045         canvas._root().tkraise()
0046 
0047     def clear(self):
0048         self.fill(0)
0049         canvas = self._canvas
0050         items = self._items
0051         self._items = []
0052         for item in items:
0053             canvas.delete(item)
0054         self._delete_turtle()
0055         self._draw_turtle()
0056 
0057     def tracer(self, flag):
0058         self._tracing = flag
0059         if not self._tracing:
0060             self._delete_turtle()
0061         self._draw_turtle()
0062 
0063     def forward(self, distance):
0064         x0, y0 = start = self._position
0065         x1 = x0 + distance * cos(self._angle*self._invradian)
0066         y1 = y0 - distance * sin(self._angle*self._invradian)
0067         self._goto(x1, y1)
0068 
0069     def backward(self, distance):
0070         self.forward(-distance)
0071 
0072     def left(self, angle):
0073         self._angle = (self._angle + angle) % self._fullcircle
0074         self._draw_turtle()
0075 
0076     def right(self, angle):
0077         self.left(-angle)
0078 
0079     def up(self):
0080         self._drawing = 0
0081 
0082     def down(self):
0083         self._drawing = 1
0084 
0085     def width(self, width):
0086         self._width = float(width)
0087 
0088     def color(self, *args):
0089         if not args:
0090             raise Error, "no color arguments"
0091         if len(args) == 1:
0092             color = args[0]
0093             if type(color) == type(""):
0094                 # Test the color first
0095                 try:
0096                     id = self._canvas.create_line(0, 0, 0, 0, fill=color)
0097                 except Tkinter.TclError:
0098                     raise Error, "bad color string: %r" % (color,)
0099                 self._set_color(color)
0100                 return
0101             try:
0102                 r, g, b = color
0103             except:
0104                 raise Error, "bad color sequence: %r" % (color,)
0105         else:
0106             try:
0107                 r, g, b = args
0108             except:
0109                 raise Error, "bad color arguments: %r" % (args,)
0110         assert 0 <= r <= 1
0111         assert 0 <= g <= 1
0112         assert 0 <= b <= 1
0113         x = 255.0
0114         y = 0.5
0115         self._set_color("#%02x%02x%02x" % (int(r*x+y), int(g*x+y), int(b*x+y)))
0116 
0117     def _set_color(self,color):
0118         self._color = color
0119         self._draw_turtle()
0120 
0121     def write(self, arg, move=0):
0122         x, y = start = self._position
0123         x = x-1 # correction -- calibrated for Windows
0124         item = self._canvas.create_text(x, y,
0125                                         text=str(arg), anchor="sw",
0126                                         fill=self._color)
0127         self._items.append(item)
0128         if move:
0129             x0, y0, x1, y1 = self._canvas.bbox(item)
0130             self._goto(x1, y1)
0131         self._draw_turtle()
0132 
0133     def fill(self, flag):
0134         if self._filling:
0135             path = tuple(self._path)
0136             smooth = self._filling < 0
0137             if len(path) > 2:
0138                 item = self._canvas._create('polygon', path,
0139                                             {'fill': self._color,
0140                                              'smooth': smooth})
0141                 self._items.append(item)
0142                 self._canvas.lower(item)
0143                 if self._tofill:
0144                     for item in self._tofill:
0145                         self._canvas.itemconfigure(item, fill=self._color)
0146                         self._items.append(item)
0147         self._path = []
0148         self._tofill = []
0149         self._filling = flag
0150         if flag:
0151             self._path.append(self._position)
0152         self.forward(0)
0153 
0154     def circle(self, radius, extent=None):
0155         if extent is None:
0156             extent = self._fullcircle
0157         x0, y0 = self._position
0158         xc = x0 - radius * sin(self._angle * self._invradian)
0159         yc = y0 - radius * cos(self._angle * self._invradian)
0160         if radius >= 0.0:
0161             start = self._angle - 90.0
0162         else:
0163             start = self._angle + 90.0
0164             extent = -extent
0165         if self._filling:
0166             if abs(extent) >= self._fullcircle:
0167                 item = self._canvas.create_oval(xc-radius, yc-radius,
0168                                                 xc+radius, yc+radius,
0169                                                 width=self._width,
0170                                                 outline="")
0171                 self._tofill.append(item)
0172             item = self._canvas.create_arc(xc-radius, yc-radius,
0173                                            xc+radius, yc+radius,
0174                                            style="chord",
0175                                            start=start,
0176                                            extent=extent,
0177                                            width=self._width,
0178                                            outline="")
0179             self._tofill.append(item)
0180         if self._drawing:
0181             if abs(extent) >= self._fullcircle:
0182                 item = self._canvas.create_oval(xc-radius, yc-radius,
0183                                                 xc+radius, yc+radius,
0184                                                 width=self._width,
0185                                                 outline=self._color)
0186                 self._items.append(item)
0187             item = self._canvas.create_arc(xc-radius, yc-radius,
0188                                            xc+radius, yc+radius,
0189                                            style="arc",
0190                                            start=start,
0191                                            extent=extent,
0192                                            width=self._width,
0193                                            outline=self._color)
0194             self._items.append(item)
0195         angle = start + extent
0196         x1 = xc + abs(radius) * cos(angle * self._invradian)
0197         y1 = yc - abs(radius) * sin(angle * self._invradian)
0198         self._angle = (self._angle + extent) % self._fullcircle
0199         self._position = x1, y1
0200         if self._filling:
0201             self._path.append(self._position)
0202         self._draw_turtle()
0203 
0204     def heading(self):
0205         return self._angle
0206 
0207     def setheading(self, angle):
0208         self._angle = angle
0209         self._draw_turtle()
0210 
0211     def window_width(self):
0212         width = self._canvas.winfo_width()
0213         if width <= 1:  # the window isn't managed by a geometry manager
0214             width = self._canvas['width']
0215         return width
0216 
0217     def window_height(self):
0218         height = self._canvas.winfo_height()
0219         if height <= 1: # the window isn't managed by a geometry manager
0220             height = self._canvas['height']
0221         return height
0222 
0223     def position(self):
0224         x0, y0 = self._origin
0225         x1, y1 = self._position
0226         return [x1-x0, -y1+y0]
0227 
0228     def setx(self, xpos):
0229         x0, y0 = self._origin
0230         x1, y1 = self._position
0231         self._goto(x0+xpos, y1)
0232 
0233     def sety(self, ypos):
0234         x0, y0 = self._origin
0235         x1, y1 = self._position
0236         self._goto(x1, y0-ypos)
0237 
0238     def goto(self, *args):
0239         if len(args) == 1:
0240             try:
0241                 x, y = args[0]
0242             except:
0243                 raise Error, "bad point argument: %r" % (args[0],)
0244         else:
0245             try:
0246                 x, y = args
0247             except:
0248                 raise Error, "bad coordinates: %r" % (args[0],)
0249         x0, y0 = self._origin
0250         self._goto(x0+x, y0-y)
0251 
0252     def _goto(self, x1, y1):
0253         x0, y0 = start = self._position
0254         self._position = map(float, (x1, y1))
0255         if self._filling:
0256             self._path.append(self._position)
0257         if self._drawing:
0258             if self._tracing:
0259                 dx = float(x1 - x0)
0260                 dy = float(y1 - y0)
0261                 distance = hypot(dx, dy)
0262                 nhops = int(distance)
0263                 item = self._canvas.create_line(x0, y0, x0, y0,
0264                                                 width=self._width,
0265                                                 capstyle="round",
0266                                                 fill=self._color)
0267                 try:
0268                     for i in range(1, 1+nhops):
0269                         x, y = x0 + dx*i/nhops, y0 + dy*i/nhops
0270                         self._canvas.coords(item, x0, y0, x, y)
0271                         self._draw_turtle((x,y))
0272                         self._canvas.update()
0273                         self._canvas.after(10)
0274                     # in case nhops==0
0275                     self._canvas.coords(item, x0, y0, x1, y1)
0276                     self._canvas.itemconfigure(item, arrow="none")
0277                 except Tkinter.TclError:
0278                     # Probably the window was closed!
0279                     return
0280             else:
0281                 item = self._canvas.create_line(x0, y0, x1, y1,
0282                                                 width=self._width,
0283                                                 capstyle="round",
0284                                                 fill=self._color)
0285             self._items.append(item)
0286         self._draw_turtle()
0287 
0288     def _draw_turtle(self,position=[]):
0289         if not self._tracing:
0290             return
0291         if position == []:
0292             position = self._position
0293         x,y = position
0294         distance = 8
0295         dx = distance * cos(self._angle*self._invradian)
0296         dy = distance * sin(self._angle*self._invradian)
0297         self._delete_turtle()
0298         self._arrow = self._canvas.create_line(x-dx,y+dy,x,y,
0299                                           width=self._width,
0300                                           arrow="last",
0301                                           capstyle="round",
0302                                           fill=self._color)
0303         self._canvas.update()
0304 
0305     def _delete_turtle(self):
0306         if self._arrow != 0:
0307             self._canvas.delete(self._arrow)
0308         self._arrow = 0
0309 
0310 
0311 
0312 _root = None
0313 _canvas = None
0314 _pen = None
0315 
0316 class Pen(RawPen):
0317 
0318     def __init__(self):
0319         global _root, _canvas
0320         if _root is None:
0321             _root = Tkinter.Tk()
0322             _root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
0323         if _canvas is None:
0324             # XXX Should have scroll bars
0325             _canvas = Tkinter.Canvas(_root, background="white")
0326             _canvas.pack(expand=1, fill="both")
0327         RawPen.__init__(self, _canvas)
0328 
0329     def _destroy(self):
0330         global _root, _canvas, _pen
0331         root = self._canvas._root()
0332         if root is _root:
0333             _pen = None
0334             _root = None
0335             _canvas = None
0336         root.destroy()
0337 
0338 
0339 def _getpen():
0340     global _pen
0341     pen = _pen
0342     if not pen:
0343         _pen = pen = Pen()
0344     return pen
0345 
0346 def degrees(): _getpen().degrees()
0347 def radians(): _getpen().radians()
0348 def reset(): _getpen().reset()
0349 def clear(): _getpen().clear()
0350 def tracer(flag): _getpen().tracer(flag)
0351 def forward(distance): _getpen().forward(distance)
0352 def backward(distance): _getpen().backward(distance)
0353 def left(angle): _getpen().left(angle)
0354 def right(angle): _getpen().right(angle)
0355 def up(): _getpen().up()
0356 def down(): _getpen().down()
0357 def width(width): _getpen().width(width)
0358 def color(*args): _getpen().color(*args)
0359 def write(arg, move=0): _getpen().write(arg, move)
0360 def fill(flag): _getpen().fill(flag)
0361 def circle(radius, extent=None): _getpen().circle(radius, extent)
0362 def goto(*args): _getpen().goto(*args)
0363 def heading(): return _getpen().heading()
0364 def setheading(angle): _getpen().setheading(angle)
0365 def position(): return _getpen().position()
0366 def window_width(): return _getpen().window_width()
0367 def window_height(): return _getpen().window_height()
0368 def setx(xpos): _getpen().setx(xpos)
0369 def sety(ypos): _getpen().sety(ypos)
0370 
0371 def demo():
0372     reset()
0373     tracer(1)
0374     up()
0375     backward(100)
0376     down()
0377     # draw 3 squares; the last filled
0378     width(3)
0379     for i in range(3):
0380         if i == 2:
0381             fill(1)
0382         for j in range(4):
0383             forward(20)
0384             left(90)
0385         if i == 2:
0386             color("maroon")
0387             fill(0)
0388         up()
0389         forward(30)
0390         down()
0391     width(1)
0392     color("black")
0393     # move out of the way
0394     tracer(0)
0395     up()
0396     right(90)
0397     forward(100)
0398     right(90)
0399     forward(100)
0400     right(180)
0401     down()
0402     # some text
0403     write("startstart", 1)
0404     write("start", 1)
0405     color("red")
0406     # staircase
0407     for i in range(5):
0408         forward(20)
0409         left(90)
0410         forward(20)
0411         right(90)
0412     # filled staircase
0413     fill(1)
0414     for i in range(5):
0415         forward(20)
0416         left(90)
0417         forward(20)
0418         right(90)
0419     fill(0)
0420     # more text
0421     write("end")
0422     if __name__ == '__main__':
0423         _root.mainloop()
0424 
0425 if __name__ == '__main__':
0426     demo()
0427 

Generated by PyXR 0.9.4
SourceForge.net Logo