0001import turtle
0002import math
0003import weakref
0004import threading
0005import sys
0006
0007from common import *
0008from ide import add_command, get_canvas
0009
0010class Turtle:
0011
0012    _all_turtles = []
0013    _turtle_count = 1
0014
0015    def __init__(self):
0016        self.pen = turtle.RawPen(get_canvas())
0017        self.pen.degrees()
0018        self._all_turtles.append(weakref.ref(self))
0019        self._count = self._turtle_count
0020        self.__class__._turtle_count += 1
0021
0022    def __repr__(self):
0023        return '<%s %i>' % (self.__class__.__name__,
0024                            self._count)
0025
0026    @logofunc()
0027    def turtle(self):
0028        return self
0029
0030    @logofunc(aliases=['fd'])
0031    def forward(self, v):
0032        add_command(self.pen.forward, v)
0033        add_command(get_canvas().update)
0034
0035    @logofunc(aliases=['back', 'bk'])
0036    def backward(self, v):
0037        add_command(self.pen.backward, v).add_command(get_canvas().update)
0038
0039    @logofunc(aliases=['lt'])
0040    def left(self, v):
0041        add_command(self.pen.left, v)
0042
0043    @logofunc(aliases=['rt'])
0044    def right(self, v):
0045        add_command(self.pen.right, v)
0046
0047    @logofunc(aliases=['pu'])
0048    def penup(self):
0049        add_command(self.pen.up)
0050
0051    @logofunc(aliases=['pd'])
0052    def pendown(self):
0053        add_command(self.pen.down)
0054
0055    @logofunc(aware=True)
0056    def penwidth(self, v):
0057        add_command(self.pen.width, v)
0058
0059    @logofunc(aliases=['pc', 'color'],
0060              arity=1)
0061    def pencolor(self, *args):
0062        add_command(self.pen.color, *args)
0063
0064    @logofunc(aliases=['ht'])
0065    def hideturtle(self):
0066        add_command(self.pen.tracer, 0)
0067
0068    @logofunc(aliases=['st'])
0069    def showturtle(self):
0070        add_command(self.pen.tracer, 1)
0071
0072    @logofunc(aliases=['turtleprint', 'turtlepr'], arity=1)
0073    def turtlewrite(self, text, move=False):
0074        if isinstance(text, list):
0075            text = ' '.join(map(str, text))
0076        else:
0077            text = str(text)
0078        add_command(self.pen.write, text, move)
0079        add_command(get_canvas().update)
0080
0081    @logofunc()
0082    def startfill(self):
0083        add_command(self.pen.fill, 1)
0084
0085    @logofunc()
0086    def endfill(self):
0087        add_command(self.pen.fill, 0)
0088        add_command(get_canvas().update)
0089
0090    @logofunc()
0091    def setxy(self, x, y):
0092        add_command(self.pen.goto, x, y)
0093        add_command(get_canvas().update)
0094
0095    @logofunc()
0096    def setx(self, x):
0097        t = self.pen
0098        add_command(t.goto, x, t.position()[1])
0099        add_command(get_canvas().update)
0100
0101    @logofunc()
0102    def sety(self, y):
0103        t = self.pen
0104        add_command(t.goto, t.position()[0], y)
0105        add_command(get_canvas().update)
0106
0107    @logofunc()
0108    def posx(self):
0109        return self.pen.position()[0]
0110
0111    @logofunc()
0112    def posy(self):
0113        return self.pen.position()[1]
0114
0115    @logofunc()
0116    def heading(self):
0117        return self.pen.heading()
0118
0119    @logofunc()
0120    def setheading(self, v):
0121        add_command(self.pen.setheading, v)
0122
0123    @logofunc()
0124    def home(self):
0125        add_command(self.pen.setheading, 0)
0126        add_command(self.pen.goto, 0, 0)
0127        add_command(get_canvas().update)
0128
0129    @logofunc(aliases=['cs', 'clearscreen'])
0130    def clear(self):
0131        self.home()
0132        add_command(self.pen.clear)
0133        add_command(get_canvas().update)
0134
0135    @logofunc(arity=1)
0136    def distance(self, other, orig=None):
0137        if orig is None:
0138            orig = self.pen
0139        return math.sqrt((orig.position()[0]-other.position()[0])**2 +
0140                         (orig.position()[1]-other.position()[1])**2)
0141
0142    @logofunc(aware=True)
0143    def clone(self, interp):
0144        new = self.__class__()
0145
0146@logofunc()
0147def allturtles():
0148    return [t() for t in Turtle._all_turtles if t()]
0149
0150@logofunc(aware=True)
0151def createturtle(interp):
0152    t = Turtle()
0153    interp.push_actor(t)