10c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#
20c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# turtle.py: a Tkinter based turtle graphics module for Python
30c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Version 1.0.1 - 24. 9. 2009
40c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#
50c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Copyright (C) 2006 - 2010  Gregor Lingl
60c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# email: glingl@aon.at
70c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#
80c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# This software is provided 'as-is', without any express or implied
90c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# warranty.  In no event will the authors be held liable for any damages
100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# arising from the use of this software.
110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#
120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Permission is granted to anyone to use this software for any purpose,
130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# including commercial applications, and to alter it and redistribute it
140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# freely, subject to the following restrictions:
150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#
160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# 1. The origin of this software must not be misrepresented; you must not
170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#    claim that you wrote the original software. If you use this software
180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#    in a product, an acknowledgment in the product documentation would be
190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#    appreciated but is not required.
200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# 2. Altered source versions must be plainly marked as such, and must not be
210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#    misrepresented as being the original software.
220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# 3. This notice may not be removed or altered from any source distribution.
230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi"""
260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTurtle graphics is a popular way for introducing programming to
270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yikids. It was part of the original Logo programming language developed
280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiby Wally Feurzig and Seymour Papert in 1966.
290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiImagine a robotic turtle starting at (0, 0) in the x-y plane. After an ``import turtle``, give it
310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yithe command turtle.forward(15), and it moves (on-screen!) 15 pixels in
320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yithe direction it is facing, drawing a line as it moves. Give it the
330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yicommand turtle.right(25), and it rotates in-place 25 degrees clockwise.
340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiBy combining together these and similar commands, intricate shapes and
360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yipictures can easily be drawn.
370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi----- turtle.py
390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiThis module is an extended reimplementation of turtle.py from the
410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiPython standard distribution up to Python 2.5. (See: http://www.python.org)
420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiIt tries to keep the merits of turtle.py and to be (nearly) 100%
440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yicompatible with it. This means in the first place to enable the
450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yilearning programmer to use all the commands, classes and methods
460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiinteractively when using the module from within IDLE run with
470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yithe -n switch.
480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiRoughly it has the following features added:
500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi- Better animation of the turtle movements, especially of turning the
520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  turtle. So the turtles can more easily be used as a visual feedback
530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  instrument by the (beginning) programmer.
540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi- Different turtle shapes, gif-images as turtle shapes, user defined
560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  and user controllable turtle shapes, among them compound
570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  (multicolored) shapes. Turtle shapes can be stretched and tilted, which
580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  makes turtles very versatile geometrical objects.
590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi- Fine control over turtle movement and screen updates via delay(),
610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  and enhanced tracer() and speed() methods.
620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi- Aliases for the most commonly used commands, like fd for forward etc.,
640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  following the early Logo traditions. This reduces the boring work of
650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  typing long sequences of commands, which often occur in a natural way
660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  when kids try to program fancy pictures on their first encounter with
670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  turtle graphics.
680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi- Turtles now have an undo()-method with configurable undo-buffer.
700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi- Some simple commands/methods for creating event driven programs
720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  (mouse-, key-, timer-events). Especially useful for programming games.
730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi- A scrollable Canvas class. The default scrollable Canvas can be
750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  extended interactively as needed while playing around with the turtle(s).
760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi- A TurtleScreen class with methods controlling background color or
780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  background image, window and canvas size and other properties of the
790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  TurtleScreen.
800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi- There is a method, setworldcoordinates(), to install a user defined
820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  coordinate-system for the TurtleScreen.
830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi- The implementation uses a 2-vector class named Vec2D, derived from tuple.
850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  This class is public, so it can be imported by the application programmer,
860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  which makes certain types of computations very natural and compact.
870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi- Appearance of the TurtleScreen and the Turtles at startup/import can be
890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  configured by means of a turtle.cfg configuration file.
900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  The default configuration mimics the appearance of the old turtle module.
910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi- If configured appropriately the module reads in docstrings from a docstring
930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  dictionary in some different language, supplied separately  and replaces
940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  the English ones by those read in. There is a utility function
950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  write_docstringdict() to write a dictionary with the original (English)
960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi  docstrings to disc, so it can serve as a template for translations.
970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiBehind the scenes there are some features included with possible
990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiextensions in mind. These will be commented and documented elsewhere.
1000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi"""
1020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_ver = "turtle 1.0b1 - for Python 2.6   -  30. 5. 2008, 18:08"
1040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#print _ver
1060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport Tkinter as TK
1080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport types
1090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport math
1100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport time
1110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport os
1120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom os.path import isfile, split, join
1140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom copy import deepcopy
1150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom math import *    ## for compatibility with old turtle module
1170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_tg_classes = ['ScrolledCanvas', 'TurtleScreen', 'Screen',
1190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi               'RawTurtle', 'Turtle', 'RawPen', 'Pen', 'Shape', 'Vec2D']
1200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_tg_screen_functions = ['addshape', 'bgcolor', 'bgpic', 'bye',
1210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'clearscreen', 'colormode', 'delay', 'exitonclick', 'getcanvas',
1220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'getshapes', 'listen', 'mode', 'onkey', 'onscreenclick', 'ontimer',
1230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'register_shape', 'resetscreen', 'screensize', 'setup',
1240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'setworldcoordinates', 'title', 'tracer', 'turtles', 'update',
1250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'window_height', 'window_width']
1260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_tg_turtle_functions = ['back', 'backward', 'begin_fill', 'begin_poly', 'bk',
1270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'circle', 'clear', 'clearstamp', 'clearstamps', 'clone', 'color',
1280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'degrees', 'distance', 'dot', 'down', 'end_fill', 'end_poly', 'fd',
1290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'fill', 'fillcolor', 'forward', 'get_poly', 'getpen', 'getscreen',
1300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'getturtle', 'goto', 'heading', 'hideturtle', 'home', 'ht', 'isdown',
1310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'isvisible', 'left', 'lt', 'onclick', 'ondrag', 'onrelease', 'pd',
1320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'pen', 'pencolor', 'pendown', 'pensize', 'penup', 'pos', 'position',
1330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'pu', 'radians', 'right', 'reset', 'resizemode', 'rt',
1340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'seth', 'setheading', 'setpos', 'setposition', 'settiltangle',
1350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'setundobuffer', 'setx', 'sety', 'shape', 'shapesize', 'showturtle',
1360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'speed', 'st', 'stamp', 'tilt', 'tiltangle', 'towards', 'tracer',
1370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'turtlesize', 'undo', 'undobufferentries', 'up', 'width',
1380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'window_height', 'window_width', 'write', 'xcor', 'ycor']
1390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_tg_utilities = ['write_docstringdict', 'done', 'mainloop']
1400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_math_functions = ['acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh',
1410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log',
1420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'log10', 'modf', 'pi', 'pow', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']
1430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi__all__ = (_tg_classes + _tg_screen_functions + _tg_turtle_functions +
1450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           _tg_utilities + _math_functions)
1460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_alias_list = ['addshape', 'backward', 'bk', 'fd', 'ht', 'lt', 'pd', 'pos',
1480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi               'pu', 'rt', 'seth', 'setpos', 'setposition', 'st',
1490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi               'turtlesize', 'up', 'width']
1500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_CFG = {"width" : 0.5,               # Screen
1520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "height" : 0.75,
1530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "canvwidth" : 400,
1540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "canvheight": 300,
1550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "leftright": None,
1560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "topbottom": None,
1570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "mode": "standard",          # TurtleScreen
1580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "colormode": 1.0,
1590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "delay": 10,
1600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "undobuffersize": 1000,      # RawTurtle
1610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "shape": "classic",
1620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "pencolor" : "black",
1630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "fillcolor" : "black",
1640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "resizemode" : "noresize",
1650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "visible" : True,
1660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "language": "english",        # docstrings
1670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "exampleturtle": "turtle",
1680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "examplescreen": "screen",
1690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "title": "Python Turtle Graphics",
1700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "using_IDLE": False
1710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi       }
1720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##print "cwd:", os.getcwd()
1740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##print "__file__:", __file__
1750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##
1760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##def show(dictionary):
1770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##    print "=========================="
1780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##    for key in sorted(dictionary.keys()):
1790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##        print key, ":", dictionary[key]
1800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##    print "=========================="
1810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##    print
1820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
1830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef config_dict(filename):
1840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Convert content of config-file into dictionary."""
1850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    f = open(filename, "r")
1860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    cfglines = f.readlines()
1870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    f.close()
1880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    cfgdict = {}
1890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for line in cfglines:
1900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        line = line.strip()
1910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if not line or line.startswith("#"):
1920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            continue
1930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
1940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            key, value = line.split("=")
1950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        except:
1960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            print "Bad line in config-file %s:\n%s" % (filename,line)
1970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            continue
1980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        key = key.strip()
1990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        value = value.strip()
2000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if value in ["True", "False", "None", "''", '""']:
2010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            value = eval(value)
2020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
2030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            try:
2040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if "." in value:
2050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    value = float(value)
2060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                else:
2070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    value = int(value)
2080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            except:
2090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pass # value need not be converted
2100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cfgdict[key] = value
2110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return cfgdict
2120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef readconfig(cfgdict):
2140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Read config-files, change configuration-dict accordingly.
2150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    If there is a turtle.cfg file in the current working directory,
2170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    read it from there. If this contains an importconfig-value,
2180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    say 'myway', construct filename turtle_mayway.cfg else use
2190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    turtle.cfg and read it from the import-directory, where
2200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    turtle.py is located.
2210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Update configuration dictionary first according to config-file,
2220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    in the import directory, then according to config-file in the
2230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    current working directory.
2240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    If no config-file is found, the default configuration is used.
2250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
2260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    default_cfg = "turtle.cfg"
2270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    cfgdict1 = {}
2280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    cfgdict2 = {}
2290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if isfile(default_cfg):
2300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cfgdict1 = config_dict(default_cfg)
2310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #print "1. Loading config-file %s from: %s" % (default_cfg, os.getcwd())
2320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if "importconfig" in cfgdict1:
2330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        default_cfg = "turtle_%s.cfg" % cfgdict1["importconfig"]
2340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    try:
2350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        head, tail = split(__file__)
2360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cfg_file2 = join(head, default_cfg)
2370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    except:
2380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cfg_file2 = ""
2390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if isfile(cfg_file2):
2400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #print "2. Loading config-file %s:" % cfg_file2
2410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cfgdict2 = config_dict(cfg_file2)
2420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##    show(_CFG)
2430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##    show(cfgdict2)
2440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    _CFG.update(cfgdict2)
2450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##    show(_CFG)
2460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##    show(cfgdict1)
2470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    _CFG.update(cfgdict1)
2480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##    show(_CFG)
2490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yitry:
2510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    readconfig(_CFG)
2520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiexcept:
2530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    print "No configfile read, reason unknown"
2540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Vec2D(tuple):
2570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """A 2 dimensional vector class, used as a helper class
2580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for implementing turtle graphics.
2590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    May be useful for turtle graphics programs also.
2600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Derived from tuple, so a vector is a tuple!
2610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Provides (for a, b vectors, k number):
2630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi       a+b vector addition
2640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi       a-b vector subtraction
2650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi       a*b inner product
2660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi       k*a and a*k multiplication with scalar
2670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi       |a| absolute value of a
2680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi       a.rotate(angle) rotation
2690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
2700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __new__(cls, x, y):
2710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return tuple.__new__(cls, (x, y))
2720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __add__(self, other):
2730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return Vec2D(self[0]+other[0], self[1]+other[1])
2740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __mul__(self, other):
2750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(other, Vec2D):
2760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self[0]*other[0]+self[1]*other[1]
2770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return Vec2D(self[0]*other, self[1]*other)
2780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __rmul__(self, other):
2790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(other, int) or isinstance(other, float):
2800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return Vec2D(self[0]*other, self[1]*other)
2810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __sub__(self, other):
2820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return Vec2D(self[0]-other[0], self[1]-other[1])
2830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __neg__(self):
2840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return Vec2D(-self[0], -self[1])
2850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __abs__(self):
2860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return (self[0]**2 + self[1]**2)**0.5
2870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def rotate(self, angle):
2880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """rotate self counterclockwise by angle
2890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
2900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        perp = Vec2D(-self[1], self[0])
2910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        angle = angle * math.pi / 180.0
2920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        c, s = math.cos(angle), math.sin(angle)
2930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return Vec2D(self[0]*c+perp[0]*s, self[1]*c+perp[1]*s)
2940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __getnewargs__(self):
2950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return (self[0], self[1])
2960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __repr__(self):
2970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return "(%.2f,%.2f)" % self
2980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
2990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##############################################################################
3010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi### From here up to line    : Tkinter - Interface for turtle.py            ###
3020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi### May be replaced by an interface to some different graphics toolkit     ###
3030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##############################################################################
3040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## helper functions for Scrolled Canvas, to forward Canvas-methods
3060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## to ScrolledCanvas class
3070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef __methodDict(cls, _dict):
3090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """helper function for Scrolled Canvas"""
3100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    baseList = list(cls.__bases__)
3110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    baseList.reverse()
3120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for _super in baseList:
3130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        __methodDict(_super, _dict)
3140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for key, value in cls.__dict__.items():
3150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if type(value) == types.FunctionType:
3160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            _dict[key] = value
3170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef __methods(cls):
3190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """helper function for Scrolled Canvas"""
3200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    _dict = {}
3210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    __methodDict(cls, _dict)
3220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return _dict.keys()
3230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi__stringBody = (
3250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    'def %(method)s(self, *args, **kw): return ' +
3260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    'self.%(attribute)s.%(method)s(*args, **kw)')
3270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef __forwardmethods(fromClass, toClass, toPart, exclude = ()):
3290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Helper functions for Scrolled Canvas, used to forward
3300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    ScrolledCanvas-methods to Tkinter.Canvas class.
3310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
3320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    _dict = {}
3330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    __methodDict(toClass, _dict)
3340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for ex in _dict.keys():
3350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if ex[:1] == '_' or ex[-1:] == '_':
3360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            del _dict[ex]
3370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for ex in exclude:
3380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if ex in _dict:
3390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            del _dict[ex]
3400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for ex in __methods(fromClass):
3410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if ex in _dict:
3420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            del _dict[ex]
3430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for method, func in _dict.items():
3450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        d = {'method': method, 'func': func}
3460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if type(toPart) == types.StringType:
3470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            execString = \
3480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                __stringBody % {'method' : method, 'attribute' : toPart}
3490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        exec execString in d
3500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fromClass.__dict__[method] = d[method]
3510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass ScrolledCanvas(TK.Frame):
3540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Modeled after the scrolled canvas class from Grayons's Tkinter book.
3550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Used as the default canvas, which pops up automatically when
3570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    using turtle graphics functions or the Turtle class.
3580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
3590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, master, width=500, height=350,
3600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                          canvwidth=600, canvheight=500):
3610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        TK.Frame.__init__(self, master, width=width, height=height)
3620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._rootwindow = self.winfo_toplevel()
3630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.width, self.height = width, height
3640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.canvwidth, self.canvheight = canvwidth, canvheight
3650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.bg = "white"
3660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._canvas = TK.Canvas(master, width=width, height=height,
3670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                 bg=self.bg, relief=TK.SUNKEN, borderwidth=2)
3680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.hscroll = TK.Scrollbar(master, command=self._canvas.xview,
3690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                    orient=TK.HORIZONTAL)
3700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.vscroll = TK.Scrollbar(master, command=self._canvas.yview)
3710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._canvas.configure(xscrollcommand=self.hscroll.set,
3720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                               yscrollcommand=self.vscroll.set)
3730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.rowconfigure(0, weight=1, minsize=0)
3740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.columnconfigure(0, weight=1, minsize=0)
3750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._canvas.grid(padx=1, in_ = self, pady=1, row=0,
3760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                column=0, rowspan=1, columnspan=1, sticky='news')
3770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
3780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                column=1, rowspan=1, columnspan=1, sticky='news')
3790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
3800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                column=0, rowspan=1, columnspan=1, sticky='news')
3810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.reset()
3820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._rootwindow.bind('<Configure>', self.onResize)
3830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
3840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def reset(self, canvwidth=None, canvheight=None, bg = None):
3850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Adjust canvas and scrollbars according to given canvas size."""
3860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if canvwidth:
3870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.canvwidth = canvwidth
3880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if canvheight:
3890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.canvheight = canvheight
3900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if bg:
3910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.bg = bg
3920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._canvas.config(bg=bg,
3930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        scrollregion=(-self.canvwidth//2, -self.canvheight//2,
3940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                       self.canvwidth//2, self.canvheight//2))
3950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._canvas.xview_moveto(0.5*(self.canvwidth - self.width + 30) /
3960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                                               self.canvwidth)
3970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._canvas.yview_moveto(0.5*(self.canvheight- self.height + 30) /
3980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                                              self.canvheight)
3990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.adjustScrolls()
4000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def adjustScrolls(self):
4030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Adjust scrollbars according to window- and canvas-size.
4040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
4050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cwidth = self._canvas.winfo_width()
4060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cheight = self._canvas.winfo_height()
4070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._canvas.xview_moveto(0.5*(self.canvwidth-cwidth)/self.canvwidth)
4080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._canvas.yview_moveto(0.5*(self.canvheight-cheight)/self.canvheight)
4090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if cwidth < self.canvwidth or cheight < self.canvheight:
4100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
4110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              column=0, rowspan=1, columnspan=1, sticky='news')
4120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
4130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              column=1, rowspan=1, columnspan=1, sticky='news')
4140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
4150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.hscroll.grid_forget()
4160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.vscroll.grid_forget()
4170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def onResize(self, event):
4190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """self-explanatory"""
4200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.adjustScrolls()
4210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def bbox(self, *args):
4230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ 'forward' method, which canvas itself has inherited...
4240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
4250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self._canvas.bbox(*args)
4260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def cget(self, *args, **kwargs):
4280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ 'forward' method, which canvas itself has inherited...
4290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
4300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self._canvas.cget(*args, **kwargs)
4310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def config(self, *args, **kwargs):
4330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ 'forward' method, which canvas itself has inherited...
4340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
4350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._canvas.config(*args, **kwargs)
4360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def bind(self, *args, **kwargs):
4380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ 'forward' method, which canvas itself has inherited...
4390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
4400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._canvas.bind(*args, **kwargs)
4410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def unbind(self, *args, **kwargs):
4430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ 'forward' method, which canvas itself has inherited...
4440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
4450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._canvas.unbind(*args, **kwargs)
4460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def focus_force(self):
4480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ 'forward' method, which canvas itself has inherited...
4490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
4500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._canvas.focus_force()
4510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi__forwardmethods(ScrolledCanvas, TK.Canvas, '_canvas')
4530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass _Root(TK.Tk):
4560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Root class for Screen based on Tkinter."""
4570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self):
4580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        TK.Tk.__init__(self)
4590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def setupcanvas(self, width, height, cwidth, cheight):
4610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._canvas = ScrolledCanvas(self, width, height, cwidth, cheight)
4620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._canvas.pack(expand=1, fill="both")
4630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _getcanvas(self):
4650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self._canvas
4660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def set_geometry(self, width, height, startx, starty):
4680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.geometry("%dx%d%+d%+d"%(width, height, startx, starty))
4690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def ondestroy(self, destroy):
4710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.wm_protocol("WM_DELETE_WINDOW", destroy)
4720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def win_width(self):
4740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.winfo_screenwidth()
4750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def win_height(self):
4770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.winfo_screenheight()
4780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiCanvas = TK.Canvas
4800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TurtleScreenBase(object):
4830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Provide the basic graphics functionality.
4840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi       Interface between Tkinter and turtle.py.
4850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi       To port turtle.py to some different graphics toolkit
4870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi       a corresponding TurtleScreenBase class has to be implemented.
4880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
4890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    @staticmethod
4910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _blankimage():
4920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """return a blank image object
4930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
4940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        img = TK.PhotoImage(width=1, height=1)
4950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        img.blank()
4960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return img
4970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
4980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    @staticmethod
4990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _image(filename):
5000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """return an image object containing the
5010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        imagedata from a gif-file named filename.
5020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
5030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return TK.PhotoImage(file=filename)
5040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, cv):
5060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.cv = cv
5070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(cv, ScrolledCanvas):
5080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            w = self.cv.canvwidth
5090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            h = self.cv.canvheight
5100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:  # expected: ordinary TK.Canvas
5110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            w = int(self.cv.cget("width"))
5120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            h = int(self.cv.cget("height"))
5130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.config(scrollregion = (-w//2, -h//2, w//2, h//2 ))
5140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.canvwidth = w
5150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.canvheight = h
5160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.xscale = self.yscale = 1.0
5170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _createpoly(self):
5190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Create an invisible polygon item on canvas self.cv)
5200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
5210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.cv.create_polygon((0, 0, 0, 0, 0, 0), fill="", outline="")
5220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _drawpoly(self, polyitem, coordlist, fill=None,
5240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                  outline=None, width=None, top=False):
5250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Configure polygonitem polyitem according to provided
5260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        arguments:
5270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        coordlist is sequence of coordinates
5280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fill is filling color
5290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        outline is outline color
5300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        top is a boolean value, which specifies if polyitem
5310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        will be put on top of the canvas' displaylist so it
5320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        will not be covered by other items.
5330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
5340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cl = []
5350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for x, y in coordlist:
5360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            cl.append(x * self.xscale)
5370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            cl.append(-y * self.yscale)
5380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.cv.coords(polyitem, *cl)
5390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if fill is not None:
5400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.itemconfigure(polyitem, fill=fill)
5410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if outline is not None:
5420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.itemconfigure(polyitem, outline=outline)
5430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if width is not None:
5440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.itemconfigure(polyitem, width=width)
5450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if top:
5460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.tag_raise(polyitem)
5470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _createline(self):
5490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Create an invisible line item on canvas self.cv)
5500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
5510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.cv.create_line(0, 0, 0, 0, fill="", width=2,
5520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                   capstyle = TK.ROUND)
5530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _drawline(self, lineitem, coordlist=None,
5550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                  fill=None, width=None, top=False):
5560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Configure lineitem according to provided arguments:
5570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        coordlist is sequence of coordinates
5580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fill is drawing color
5590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        width is width of drawn line.
5600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        top is a boolean value, which specifies if polyitem
5610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        will be put on top of the canvas' displaylist so it
5620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        will not be covered by other items.
5630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
5640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if coordlist is not None:
5650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            cl = []
5660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for x, y in coordlist:
5670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                cl.append(x * self.xscale)
5680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                cl.append(-y * self.yscale)
5690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.coords(lineitem, *cl)
5700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if fill is not None:
5710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.itemconfigure(lineitem, fill=fill)
5720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if width is not None:
5730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.itemconfigure(lineitem, width=width)
5740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if top:
5750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.tag_raise(lineitem)
5760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _delete(self, item):
5780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Delete graphics item from canvas.
5790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If item is"all" delete all graphics items.
5800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
5810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.cv.delete(item)
5820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _update(self):
5840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Redraw graphics items on canvas
5850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
5860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.cv.update()
5870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _delay(self, delay):
5890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Delay subsequent canvas actions for delay ms."""
5900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.cv.after(delay)
5910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
5920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _iscolorstring(self, color):
5930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Check if the string color is a legal Tkinter color string.
5940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
5950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
5960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            rgb = self.cv.winfo_rgb(color)
5970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ok = True
5980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        except TK.TclError:
5990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            ok = False
6000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return ok
6010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _bgcolor(self, color=None):
6030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set canvas' backgroundcolor if color is not None,
6040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else return backgroundcolor."""
6050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if color is not None:
6060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.config(bg = color)
6070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._update()
6080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
6090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self.cv.cget("bg")
6100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _write(self, pos, txt, align, font, pencolor):
6120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Write txt at pos in canvas with specified font
6130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        and color.
6140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Return text item and x-coord of right bottom corner
6150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        of text's bounding box."""
6160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        x, y = pos
6170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        x = x * self.xscale
6180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        y = y * self.yscale
6190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        anchor = {"left":"sw", "center":"s", "right":"se" }
6200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        item = self.cv.create_text(x-1, -y, text = txt, anchor = anchor[align],
6210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                        fill = pencolor, font = font)
6220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        x0, y0, x1, y1 = self.cv.bbox(item)
6230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.cv.update()
6240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return item, x1-1
6250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##    def _dot(self, pos, size, color):
6270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##        """may be implemented for some other graphics toolkit"""
6280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _onclick(self, item, fun, num=1, add=None):
6300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Bind fun to mouse-click event on turtle.
6310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fun must be a function with two arguments, the coordinates
6320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        of the clicked point on the canvas.
6330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        num, the number of the mouse-button defaults to 1
6340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
6350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if fun is None:
6360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.tag_unbind(item, "<Button-%s>" % num)
6370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
6380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def eventfun(event):
6390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                x, y = (self.cv.canvasx(event.x)/self.xscale,
6400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        -self.cv.canvasy(event.y)/self.yscale)
6410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                fun(x, y)
6420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.tag_bind(item, "<Button-%s>" % num, eventfun, add)
6430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _onrelease(self, item, fun, num=1, add=None):
6450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Bind fun to mouse-button-release event on turtle.
6460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fun must be a function with two arguments, the coordinates
6470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        of the point on the canvas where mouse button is released.
6480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        num, the number of the mouse-button defaults to 1
6490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If a turtle is clicked, first _onclick-event will be performed,
6510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        then _onscreensclick-event.
6520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
6530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if fun is None:
6540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.tag_unbind(item, "<Button%s-ButtonRelease>" % num)
6550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
6560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def eventfun(event):
6570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                x, y = (self.cv.canvasx(event.x)/self.xscale,
6580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        -self.cv.canvasy(event.y)/self.yscale)
6590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                fun(x, y)
6600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.tag_bind(item, "<Button%s-ButtonRelease>" % num,
6610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                             eventfun, add)
6620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _ondrag(self, item, fun, num=1, add=None):
6640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Bind fun to mouse-move-event (with pressed mouse button) on turtle.
6650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fun must be a function with two arguments, the coordinates of the
6660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        actual mouse position on the canvas.
6670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        num, the number of the mouse-button defaults to 1
6680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Every sequence of mouse-move-events on a turtle is preceded by a
6700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mouse-click event on that turtle.
6710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
6720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if fun is None:
6730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.tag_unbind(item, "<Button%s-Motion>" % num)
6740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
6750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def eventfun(event):
6760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                try:
6770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    x, y = (self.cv.canvasx(event.x)/self.xscale,
6780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                           -self.cv.canvasy(event.y)/self.yscale)
6790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    fun(x, y)
6800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                except:
6810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    pass
6820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.tag_bind(item, "<Button%s-Motion>" % num, eventfun, add)
6830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _onscreenclick(self, fun, num=1, add=None):
6850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Bind fun to mouse-click event on canvas.
6860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fun must be a function with two arguments, the coordinates
6870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        of the clicked point on the canvas.
6880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        num, the number of the mouse-button defaults to 1
6890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
6900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If a turtle is clicked, first _onclick-event will be performed,
6910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        then _onscreensclick-event.
6920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
6930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if fun is None:
6940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.unbind("<Button-%s>" % num)
6950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
6960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def eventfun(event):
6970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                x, y = (self.cv.canvasx(event.x)/self.xscale,
6980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        -self.cv.canvasy(event.y)/self.yscale)
6990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                fun(x, y)
7000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.bind("<Button-%s>" % num, eventfun, add)
7010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _onkey(self, fun, key):
7030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Bind fun to key-release event of key.
7040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Canvas must have focus. See method listen
7050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
7060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if fun is None:
7070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.unbind("<KeyRelease-%s>" % key, None)
7080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
7090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            def eventfun(event):
7100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                fun()
7110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.bind("<KeyRelease-%s>" % key, eventfun)
7120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _listen(self):
7140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set focus on canvas (in order to collect key-events)
7150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
7160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.cv.focus_force()
7170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _ontimer(self, fun, t):
7190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Install a timer, which calls fun after t milliseconds.
7200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
7210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if t == 0:
7220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.after_idle(fun)
7230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
7240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.after(t, fun)
7250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _createimage(self, image):
7270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Create and return image item on canvas.
7280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
7290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.cv.create_image(0, 0, image=image)
7300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _drawimage(self, item, (x, y), image):
7320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Configure image item as to draw image object
7330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        at position (x,y) on canvas)
7340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
7350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.cv.coords(item, (x * self.xscale, -y * self.yscale))
7360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.cv.itemconfig(item, image=image)
7370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _setbgpic(self, item, image):
7390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Configure image item as to draw image object
7400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        at center of canvas. Set item to the first item
7410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        in the displaylist, so it will be drawn below
7420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        any other item ."""
7430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.cv.itemconfig(item, image=image)
7440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.cv.tag_lower(item)
7450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _type(self, item):
7470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return 'line' or 'polygon' or 'image' depending on
7480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        type of item.
7490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
7500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.cv.type(item)
7510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _pointlist(self, item):
7530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """returns list of coordinate-pairs of points of item
7540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for insiders):
7550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> from turtle import *
7560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> getscreen()._pointlist(getturtle().turtle._item)
7570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        [(0.0, 9.9999999999999982), (0.0, -9.9999999999999982),
7580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (9.9999999999999982, 0.0)]
7590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> """
7600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cl = self.cv.coords(item)
7610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pl = [(cl[i], -cl[i+1]) for i in range(0, len(cl), 2)]
7620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return  pl
7630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _setscrollregion(self, srx1, sry1, srx2, sry2):
7650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.cv.config(scrollregion=(srx1, sry1, srx2, sry2))
7660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _rescale(self, xscalefactor, yscalefactor):
7680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        items = self.cv.find_all()
7690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for item in items:
7700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            coordinates = self.cv.coords(item)
7710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            newcoordlist = []
7720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            while coordinates:
7730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                x, y = coordinates[:2]
7740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                newcoordlist.append(x * xscalefactor)
7750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                newcoordlist.append(y * yscalefactor)
7760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                coordinates = coordinates[2:]
7770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.cv.coords(item, *newcoordlist)
7780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _resize(self, canvwidth=None, canvheight=None, bg=None):
7800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Resize the canvas the turtles are drawing on. Does
7810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        not alter the drawing window.
7820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
7830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # needs amendment
7840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if not isinstance(self.cv, ScrolledCanvas):
7850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self.canvwidth, self.canvheight
7860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if canvwidth is canvheight is bg is None:
7870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self.cv.canvwidth, self.cv.canvheight
7880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if canvwidth is not None:
7890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.canvwidth = canvwidth
7900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if canvheight is not None:
7910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.canvheight = canvheight
7920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.cv.reset(canvwidth, canvheight, bg)
7930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
7940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _window_size(self):
7950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Return the width and height of the turtle window.
7960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
7970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        width = self.cv.winfo_width()
7980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if width <= 1:  # the window isn't managed by a geometry manager
7990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            width = self.cv['width']
8000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        height = self.cv.winfo_height()
8010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if height <= 1: # the window isn't managed by a geometry manager
8020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            height = self.cv['height']
8030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return width, height
8040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##############################################################################
8070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi###                  End of Tkinter - interface                            ###
8080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##############################################################################
8090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Terminator (Exception):
8120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Will be raised in TurtleScreen.update, if _RUNNING becomes False.
8130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    This stops execution of a turtle graphics script.
8150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Main purpose: use in the Demo-Viewer turtle.Demo.py.
8160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
8170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    pass
8180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TurtleGraphicsError(Exception):
8210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Some TurtleGraphics Error
8220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
8230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Shape(object):
8260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Data structure modeling shapes.
8270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    attribute _type is one of "polygon", "image", "compound"
8290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    attribute _data is - depending on _type a poygon-tuple,
8300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    an image or a list constructed using the addcomponent method.
8310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
8320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, type_, data=None):
8330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._type = type_
8340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if type_ == "polygon":
8350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if isinstance(data, list):
8360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                data = tuple(data)
8370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif type_ == "image":
8380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if isinstance(data, str):
8390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if data.lower().endswith(".gif") and isfile(data):
8400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    data = TurtleScreen._image(data)
8410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                # else data assumed to be Photoimage
8420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif type_ == "compound":
8430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            data = []
8440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
8450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            raise TurtleGraphicsError("There is no shape type %s" % type_)
8460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._data = data
8470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def addcomponent(self, poly, fill, outline=None):
8490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Add component to a shape of type compound.
8500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments: poly is a polygon, i. e. a tuple of number pairs.
8520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fill is the fillcolor of the component,
8530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        outline is the outline color of the component.
8540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        call (for a Shapeobject namend s):
8560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        --   s.addcomponent(((0,0), (10,10), (-10,10)), "red", "blue")
8570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example:
8590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
8600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> s = Shape("compound")
8610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> s.addcomponent(poly, "red", "blue")
8620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> # .. add more components and then use register_shape()
8630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
8640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._type != "compound":
8650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            raise TurtleGraphicsError("Cannot add component to %s Shape"
8660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                                                % self._type)
8670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if outline is None:
8680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            outline = fill
8690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._data.append([poly, fill, outline])
8700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
8720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Tbuffer(object):
8730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Ring buffer used as undobuffer for RawTurtle objects."""
8740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, bufsize=10):
8750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.bufsize = bufsize
8760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.buffer = [[None]] * bufsize
8770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.ptr = -1
8780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.cumulate = False
8790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def reset(self, bufsize=None):
8800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if bufsize is None:
8810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for i in range(self.bufsize):
8820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.buffer[i] = [None]
8830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
8840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.bufsize = bufsize
8850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.buffer = [[None]] * bufsize
8860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.ptr = -1
8870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def push(self, item):
8880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.bufsize > 0:
8890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if not self.cumulate:
8900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.ptr = (self.ptr + 1) % self.bufsize
8910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.buffer[self.ptr] = item
8920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
8930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.buffer[self.ptr].append(item)
8940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def pop(self):
8950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.bufsize > 0:
8960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            item = self.buffer[self.ptr]
8970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if item is None:
8980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                return None
8990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
9000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.buffer[self.ptr] = [None]
9010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.ptr = (self.ptr - 1) % self.bufsize
9020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                return (item)
9030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def nr_of_items(self):
9040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.bufsize - self.buffer.count([None])
9050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __repr__(self):
9060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return str(self.buffer) + " " + str(self.ptr)
9070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TurtleScreen(TurtleScreenBase):
9110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Provides screen oriented methods like setbg etc.
9120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Only relies upon the methods of TurtleScreenBase and NOT
9140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    upon components of the underlying graphics toolkit -
9150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    which is Tkinter in this case.
9160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
9170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi#    _STANDARD_DELAY = 5
9180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    _RUNNING = True
9190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, cv, mode=_CFG["mode"],
9210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                 colormode=_CFG["colormode"], delay=_CFG["delay"]):
9220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._shapes = {
9230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                   "arrow" : Shape("polygon", ((-10,0), (10,0), (0,10))),
9240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                  "turtle" : Shape("polygon", ((0,16), (-2,14), (-1,10), (-4,7),
9250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              (-7,9), (-9,8), (-6,5), (-7,1), (-5,-3), (-8,-6),
9260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              (-6,-8), (-4,-5), (0,-7), (4,-5), (6,-8), (8,-6),
9270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              (5,-3), (7,1), (6,5), (9,8), (7,9), (4,7), (1,10),
9280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              (2,14))),
9290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                  "circle" : Shape("polygon", ((10,0), (9.51,3.09), (8.09,5.88),
9300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              (5.88,8.09), (3.09,9.51), (0,10), (-3.09,9.51),
9310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              (-5.88,8.09), (-8.09,5.88), (-9.51,3.09), (-10,0),
9320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              (-9.51,-3.09), (-8.09,-5.88), (-5.88,-8.09),
9330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              (-3.09,-9.51), (-0.00,-10.00), (3.09,-9.51),
9340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              (5.88,-8.09), (8.09,-5.88), (9.51,-3.09))),
9350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                  "square" : Shape("polygon", ((10,-10), (10,10), (-10,10),
9360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              (-10,-10))),
9370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                "triangle" : Shape("polygon", ((10,-5.77), (0,11.55),
9380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              (-10,-5.77))),
9390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                  "classic": Shape("polygon", ((0,0),(-5,-9),(0,-7),(5,-9))),
9400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                   "blank" : Shape("image", self._blankimage())
9410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                  }
9420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._bgpics = {"nopic" : ""}
9440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        TurtleScreenBase.__init__(self, cv)
9460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._mode = mode
9470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._delayvalue = delay
9480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._colormode = _CFG["colormode"]
9490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._keys = []
9500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.clear()
9510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def clear(self):
9530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Delete all drawings and all turtles from the TurtleScreen.
9540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Reset empty TurtleScreen to its initial state: white background,
9560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        no backgroundimage, no eventbindings and tracing on.
9570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
9590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
9610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.clear()
9620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Note: this method is not available as function.
9640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
9650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._delayvalue = _CFG["delay"]
9660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._colormode = _CFG["colormode"]
9670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._delete("all")
9680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._bgpic = self._createimage("")
9690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._bgpicname = "nopic"
9700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._tracing = 1
9710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._updatecounter = 0
9720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._turtles = []
9730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.bgcolor("white")
9740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for btn in 1, 2, 3:
9750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.onclick(None, btn)
9760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for key in self._keys[:]:
9770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.onkey(None, key)
9780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Turtle._pen = None
9790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def mode(self, mode=None):
9810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set turtle-mode ('standard', 'logo' or 'world') and perform reset.
9820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Optional argument:
9840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mode -- on of the strings 'standard', 'logo' or 'world'
9850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Mode 'standard' is compatible with turtle.py.
9870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Mode 'logo' is compatible with most Logo-Turtle-Graphics.
9880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Mode 'world' uses userdefined 'worldcoordinates'. *Attention*: in
9890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        this mode angles appear distorted if x/y unit-ratio doesn't equal 1.
9900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If mode is not given, return the current mode.
9910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi             Mode      Initial turtle heading     positive angles
9930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         ------------|-------------------------|-------------------
9940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          'standard'    to the right (east)       counterclockwise
9950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'logo'        upward    (north)         clockwise
9960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
9970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Examples:
9980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> mode('logo')   # resets turtle heading to north
9990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> mode()
10000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'logo'
10010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
10020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if mode is None:
10030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self._mode
10040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mode = mode.lower()
10050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if mode not in ["standard", "logo", "world"]:
10060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            raise TurtleGraphicsError("No turtle-graphics-mode %s" % mode)
10070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._mode = mode
10080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if mode in ["standard", "logo"]:
10090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._setscrollregion(-self.canvwidth//2, -self.canvheight//2,
10100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                       self.canvwidth//2, self.canvheight//2)
10110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.xscale = self.yscale = 1.0
10120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.reset()
10130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def setworldcoordinates(self, llx, lly, urx, ury):
10150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set up a user defined coordinate-system.
10160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
10180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        llx -- a number, x-coordinate of lower left corner of canvas
10190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        lly -- a number, y-coordinate of lower left corner of canvas
10200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        urx -- a number, x-coordinate of upper right corner of canvas
10210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ury -- a number, y-coordinate of upper right corner of canvas
10220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Set up user coodinat-system and switch to mode 'world' if necessary.
10240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        This performs a screen.reset. If mode 'world' is already active,
10250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        all drawings are redrawn according to the new coordinates.
10260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        But ATTENTION: in user-defined coordinatesystems angles may appear
10280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        distorted. (see Screen.mode())
10290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
10310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.setworldcoordinates(-10,-0.5,50,1.5)
10320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> for _ in range(36):
10330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     left(10)
10340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     forward(0.5)
10350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
10360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.mode() != "world":
10370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.mode("world")
10380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        xspan = float(urx - llx)
10390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        yspan = float(ury - lly)
10400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        wx, wy = self._window_size()
10410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.screensize(wx-20, wy-20)
10420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        oldxscale, oldyscale = self.xscale, self.yscale
10430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.xscale = self.canvwidth / xspan
10440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.yscale = self.canvheight / yspan
10450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        srx1 = llx * self.xscale
10460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        sry1 = -ury * self.yscale
10470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        srx2 = self.canvwidth + srx1
10480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        sry2 = self.canvheight + sry1
10490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._setscrollregion(srx1, sry1, srx2, sry2)
10500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._rescale(self.xscale/oldxscale, self.yscale/oldyscale)
10510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.update()
10520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def register_shape(self, name, shape=None):
10540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Adds a turtle shape to TurtleScreen's shapelist.
10550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
10570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (1) name is the name of a gif-file and shape is None.
10580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            Installs the corresponding image shape.
10590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            !! Image-shapes DO NOT rotate when turning the turtle,
10600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            !! so they do not display the heading of the turtle!
10610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (2) name is an arbitrary string and shape is a tuple
10620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            of pairs of coordinates. Installs the corresponding
10630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            polygon shape
10640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (3) name is an arbitrary string and shape is a
10650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            (compound) Shape object. Installs the corresponding
10660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            compound shape.
10670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        To use a shape, you have to issue the command shape(shapename).
10680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        call: register_shape("turtle.gif")
10700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        --or: register_shape("tri", ((0,0), (10,10), (-10,10)))
10710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
10730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.register_shape("triangle", ((5,-3),(0,5),(-5,-3)))
10740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
10760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if shape is None:
10770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            # image
10780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if name.lower().endswith(".gif"):
10790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                shape = Shape("image", self._image(name))
10800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
10810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                raise TurtleGraphicsError("Bad arguments for register_shape.\n"
10820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                          + "Use  help(register_shape)" )
10830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif isinstance(shape, tuple):
10840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            shape = Shape("polygon", shape)
10850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ## else shape assumed to be Shape-instance
10860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._shapes[name] = shape
10870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # print "shape added:" , self._shapes
10880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _colorstr(self, color):
10900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return color string corresponding to args.
10910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Argument may be a string or a tuple of three
10930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        numbers corresponding to actual colormode,
10940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        i.e. in the range 0<=n<=colormode.
10950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
10960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If the argument doesn't represent a color,
10970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        an error is raised.
10980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
10990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if len(color) == 1:
11000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            color = color[0]
11010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(color, str):
11020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self._iscolorstring(color) or color == "":
11030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                return color
11040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
11050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                raise TurtleGraphicsError("bad color string: %s" % str(color))
11060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
11070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            r, g, b = color
11080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        except:
11090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            raise TurtleGraphicsError("bad color arguments: %s" % str(color))
11100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._colormode == 1.0:
11110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            r, g, b = [round(255.0*x) for x in (r, g, b)]
11120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)):
11130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            raise TurtleGraphicsError("bad color sequence: %s" % str(color))
11140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return "#%02x%02x%02x" % (r, g, b)
11150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _color(self, cstr):
11170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if not cstr.startswith("#"):
11180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return cstr
11190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if len(cstr) == 7:
11200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            cl = [int(cstr[i:i+2], 16) for i in (1, 3, 5)]
11210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif len(cstr) == 4:
11220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            cl = [16*int(cstr[h], 16) for h in cstr[1:]]
11230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
11240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            raise TurtleGraphicsError("bad colorstring: %s" % cstr)
11250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return tuple([c * self._colormode/255 for c in cl])
11260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def colormode(self, cmode=None):
11280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return the colormode or set it to 1.0 or 255.
11290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Optional argument:
11310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cmode -- one of the values 1.0 or 255
11320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        r, g, b values of colortriples have to be in range 0..cmode.
11340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
11360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.colormode()
11370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        1.0
11380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.colormode(255)
11390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> pencolor(240,160,80)
11400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
11410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if cmode is None:
11420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self._colormode
11430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if cmode == 1.0:
11440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._colormode = float(cmode)
11450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif cmode == 255:
11460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._colormode = int(cmode)
11470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def reset(self):
11490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Reset all Turtles on the Screen to their initial state.
11500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
11520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
11540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.reset()
11550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
11560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for turtle in self._turtles:
11570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            turtle._setmode(self._mode)
11580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            turtle.reset()
11590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def turtles(self):
11610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return the list of turtles on the screen.
11620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
11640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.turtles()
11650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        [<turtle.Turtle object at 0x00E11FB0>]
11660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
11670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self._turtles
11680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def bgcolor(self, *args):
11700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set or return backgroundcolor of the TurtleScreen.
11710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments (if given): a color string or three numbers
11730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        in the range 0..colormode or a 3-tuple of such numbers.
11740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
11760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.bgcolor("orange")
11770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.bgcolor()
11780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'orange'
11790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.bgcolor(0.5,0,0.5)
11800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.bgcolor()
11810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        '#800080'
11820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
11830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if args:
11840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            color = self._colorstr(args)
11850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
11860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            color = None
11870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        color = self._bgcolor(color)
11880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if color is not None:
11890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            color = self._color(color)
11900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return color
11910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def tracer(self, n=None, delay=None):
11930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Turns turtle animation on/off and set delay for update drawings.
11940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Optional arguments:
11960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        n -- nonnegative  integer
11970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        delay -- nonnegative  integer
11980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
11990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If n is given, only each n-th regular screen update is really performed.
12000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (Can be used to accelerate the drawing of complex graphics.)
12010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Second arguments sets delay value (see RawTurtle.delay())
12020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
12040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.tracer(8, 25)
12050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> dist = 2
12060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> for i in range(200):
12070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     fd(dist)
12080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     rt(90)
12090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     dist += 2
12100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
12110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if n is None:
12120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self._tracing
12130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._tracing = int(n)
12140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._updatecounter = 0
12150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if delay is not None:
12160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._delayvalue = int(delay)
12170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._tracing:
12180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.update()
12190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def delay(self, delay=None):
12210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Return or set the drawing delay in milliseconds.
12220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Optional argument:
12240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        delay -- positive integer
12250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
12270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.delay(15)
12280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.delay()
12290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        15
12300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
12310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if delay is None:
12320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self._delayvalue
12330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._delayvalue = int(delay)
12340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _incrementudc(self):
12360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Increment upadate counter."""
12370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if not TurtleScreen._RUNNING:
12380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            TurtleScreen._RUNNNING = True
12390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            raise Terminator
12400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._tracing > 0:
12410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._updatecounter += 1
12420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._updatecounter %= self._tracing
12430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def update(self):
12450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Perform a TurtleScreen update.
12460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
12470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tracing = self._tracing
12480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._tracing = True
12490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for t in self.turtles():
12500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            t._update_data()
12510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            t._drawturtle()
12520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._tracing = tracing
12530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._update()
12540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def window_width(self):
12560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Return the width of the turtle window.
12570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
12590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.window_width()
12600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        640
12610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
12620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self._window_size()[0]
12630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def window_height(self):
12650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Return the height of the turtle window.
12660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
12680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.window_height()
12690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        480
12700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
12710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self._window_size()[1]
12720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def getcanvas(self):
12740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return the Canvas of this TurtleScreen.
12750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
12770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Screen instance named screen):
12790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> cv = screen.getcanvas()
12800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> cv
12810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        <turtle.ScrolledCanvas instance at 0x010742D8>
12820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
12830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.cv
12840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def getshapes(self):
12860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return a list of names of all currently available turtle shapes.
12870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
12890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
12910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.getshapes()
12920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ['arrow', 'blank', 'circle', ... , 'turtle']
12930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
12940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return sorted(self._shapes.keys())
12950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def onclick(self, fun, btn=1, add=None):
12970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Bind fun to mouse-click event on canvas.
12980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
12990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
13000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fun -- a function with two arguments, the coordinates of the
13010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi               clicked point on the canvas.
13020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        num -- the number of the mouse-button, defaults to 1
13030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen
13050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        and a Turtle instance named turtle):
13060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.onclick(goto)
13080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> # Subsequently clicking into the TurtleScreen will
13090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> # make the turtle move to the clicked point.
13100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.onclick(None)
13110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
13120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._onscreenclick(fun, btn, add)
13130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def onkey(self, fun, key):
13150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Bind fun to key-release event of key.
13160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
13180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fun -- a function with no arguments
13190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        key -- a string: key (e.g. "a") or key-symbol (e.g. "space")
13200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        In order to be able to register key-events, TurtleScreen
13220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        must have focus. (See method listen.)
13230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
13250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> def f():
13270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     fd(50)
13280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     lt(60)
13290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...
13300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.onkey(f, "Up")
13310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.listen()
13320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Subsequently the turtle can be moved by repeatedly pressing
13340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        the up-arrow key, consequently drawing a hexagon
13350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
13370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if fun is None:
13380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if key in self._keys:
13390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self._keys.remove(key)
13400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif key not in self._keys:
13410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._keys.append(key)
13420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._onkey(fun, key)
13430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def listen(self, xdummy=None, ydummy=None):
13450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set focus on TurtleScreen (in order to collect key-events)
13460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No arguments.
13480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Dummy arguments are provided in order
13490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        to be able to pass listen to the onclick method.
13500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
13520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.listen()
13530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
13540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._listen()
13550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def ontimer(self, fun, t=0):
13570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Install a timer, which calls fun after t milliseconds.
13580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
13600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fun -- a function with no arguments.
13610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        t -- a number >= 0
13620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
13640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> running = True
13660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> def f():
13670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     if running:
13680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...             fd(50)
13690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...             lt(60)
13700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...             screen.ontimer(f, 250)
13710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...
13720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> f()   # makes the turtle marching around
13730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> running = False
13740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
13750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._ontimer(fun, t)
13760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def bgpic(self, picname=None):
13780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set background image or return name of current backgroundimage.
13790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Optional argument:
13810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        picname -- a string, name of a gif-file or "nopic".
13820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If picname is a filename, set the corresponding image as background.
13840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If picname is "nopic", delete backgroundimage, if present.
13850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If picname is None, return the filename of the current backgroundimage.
13860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
13870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
13880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.bgpic()
13890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'nopic'
13900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.bgpic("landscape.gif")
13910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.bgpic()
13920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'landscape.gif'
13930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
13940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if picname is None:
13950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self._bgpicname
13960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if picname not in self._bgpics:
13970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._bgpics[picname] = self._image(picname)
13980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._setbgpic(self._bgpic, self._bgpics[picname])
13990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._bgpicname = picname
14000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def screensize(self, canvwidth=None, canvheight=None, bg=None):
14020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Resize the canvas the turtles are drawing on.
14030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Optional arguments:
14050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        canvwidth -- positive integer, new width of canvas in pixels
14060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        canvheight --  positive integer, new height of canvas in pixels
14070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        bg -- colorstring or color-tuple, new backgroundcolor
14080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If no arguments are given, return current (canvaswidth, canvasheight)
14090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Do not alter the drawing window. To observe hidden parts of
14110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        the canvas use the scrollbars. (Can make visible those parts
14120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        of a drawing, which were outside the canvas before!)
14130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
14150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.screensize(2000,1500)
14160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> # e. g. to search for an erroneously escaped turtle ;-)
14170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
14180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self._resize(canvwidth, canvheight, bg)
14190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    onscreenclick = onclick
14210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    resetscreen = reset
14220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    clearscreen = clear
14230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    addshape = register_shape
14240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TNavigator(object):
14260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Navigation part of the RawTurtle.
14270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Implements methods for turtle movement.
14280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
14290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    START_ORIENTATION = {
14300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "standard": Vec2D(1.0, 0.0),
14310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "world"   : Vec2D(1.0, 0.0),
14320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        "logo"    : Vec2D(0.0, 1.0)  }
14330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    DEFAULT_MODE = "standard"
14340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    DEFAULT_ANGLEOFFSET = 0
14350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    DEFAULT_ANGLEORIENT = 1
14360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, mode=DEFAULT_MODE):
14380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._angleOffset = self.DEFAULT_ANGLEOFFSET
14390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._angleOrient = self.DEFAULT_ANGLEORIENT
14400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._mode = mode
14410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.undobuffer = None
14420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.degrees()
14430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._mode = None
14440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._setmode(mode)
14450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        TNavigator.reset(self)
14460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def reset(self):
14480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """reset turtle to its initial values
14490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Will be overwritten by parent class
14510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
14520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._position = Vec2D(0.0, 0.0)
14530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._orient =  TNavigator.START_ORIENTATION[self._mode]
14540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _setmode(self, mode=None):
14560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set turtle-mode to 'standard', 'world' or 'logo'.
14570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
14580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if mode is None:
14590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self._mode
14600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if mode not in ["standard", "logo", "world"]:
14610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return
14620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._mode = mode
14630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if mode in ["standard", "world"]:
14640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._angleOffset = 0
14650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._angleOrient = 1
14660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else: # mode == "logo":
14670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._angleOffset = self._fullcircle/4.
14680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._angleOrient = -1
14690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _setDegreesPerAU(self, fullcircle):
14710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Helper function for degrees() and radians()"""
14720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._fullcircle = fullcircle
14730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._degreesPerAU = 360/fullcircle
14740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._mode == "standard":
14750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._angleOffset = 0
14760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
14770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._angleOffset = fullcircle/4.
14780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def degrees(self, fullcircle=360.0):
14800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Set angle measurement units to degrees.
14810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Optional argument:
14830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fullcircle -  a number
14840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Set angle measurement units, i. e. set number
14860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        of 'degrees' for a full circle. Dafault value is
14870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        360 degrees.
14880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
14900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.left(90)
14910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.heading()
14920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        90
14930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
14940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Change angle measurement unit to grad (also known as gon,
14950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        grade, or gradian and equals 1/100-th of the right angle.)
14960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.degrees(400.0)
14970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.heading()
14980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        100
14990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
15010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._setDegreesPerAU(fullcircle)
15020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def radians(self):
15040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Set the angle measurement units to radians.
15050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No arguments.
15070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
15090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.heading()
15100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        90
15110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.radians()
15120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.heading()
15130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        1.5707963267948966
15140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
15150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._setDegreesPerAU(2*math.pi)
15160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _go(self, distance):
15180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """move turtle forward by specified distance"""
15190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ende = self._position + self._orient * distance
15200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._goto(ende)
15210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _rotate(self, angle):
15230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Turn turtle counterclockwise by specified angle if angle > 0."""
15240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        angle *= self._degreesPerAU
15250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._orient = self._orient.rotate(angle)
15260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _goto(self, end):
15280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """move turtle to position end."""
15290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._position = end
15300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def forward(self, distance):
15320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Move the turtle forward by the specified distance.
15330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Aliases: forward | fd
15350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Argument:
15370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        distance -- a number (integer or float)
15380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Move the turtle forward by the specified distance, in the direction
15400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        the turtle is headed.
15410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
15430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.position()
15440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (0.00, 0.00)
15450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(25)
15460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.position()
15470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (25.00,0.00)
15480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(-75)
15490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.position()
15500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (-50.00,0.00)
15510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
15520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._go(distance)
15530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def back(self, distance):
15550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Move the turtle backward by distance.
15560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Aliases: back | backward | bk
15580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Argument:
15600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        distance -- a number
15610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Move the turtle backward by distance ,opposite to the direction the
15630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle is headed. Do not change the turtle's heading.
15640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
15660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.position()
15670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (0.00, 0.00)
15680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.backward(30)
15690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.position()
15700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (-30.00, 0.00)
15710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
15720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._go(-distance)
15730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def right(self, angle):
15750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Turn turtle right by angle units.
15760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Aliases: right | rt
15780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Argument:
15800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        angle -- a number (integer or float)
15810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Turn turtle right by angle units. (Units are by default degrees,
15830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        but can be set via the degrees() and radians() functions.)
15840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Angle orientation depends on mode. (See this.)
15850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
15870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.heading()
15880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        22.0
15890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.right(45)
15900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.heading()
15910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        337.0
15920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
15930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._rotate(-angle)
15940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def left(self, angle):
15960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Turn turtle left by angle units.
15970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
15980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Aliases: left | lt
15990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Argument:
16010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        angle -- a number (integer or float)
16020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Turn turtle left by angle units. (Units are by default degrees,
16040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        but can be set via the degrees() and radians() functions.)
16050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Angle orientation depends on mode. (See this.)
16060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
16080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.heading()
16090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        22.0
16100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.left(45)
16110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.heading()
16120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        67.0
16130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
16140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._rotate(angle)
16150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def pos(self):
16170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return the turtle's current location (x,y), as a Vec2D-vector.
16180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Aliases: pos | position
16200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No arguments.
16220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
16240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pos()
16250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (0.00, 240.00)
16260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
16270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self._position
16280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def xcor(self):
16300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Return the turtle's x coordinate.
16310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No arguments.
16330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
16350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> reset()
16360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.left(60)
16370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(100)
16380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> print turtle.xcor()
16390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        50.0
16400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
16410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self._position[0]
16420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def ycor(self):
16440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Return the turtle's y coordinate
16450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ---
16460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No arguments.
16470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
16490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> reset()
16500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.left(60)
16510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(100)
16520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> print turtle.ycor()
16530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        86.6025403784
16540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
16550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self._position[1]
16560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def goto(self, x, y=None):
16590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Move turtle to an absolute position.
16600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Aliases: setpos | setposition | goto:
16620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
16640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        x -- a number      or     a pair/vector of numbers
16650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        y -- a number             None
16660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        call: goto(x, y)         # two coordinates
16680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        --or: goto((x, y))       # a pair (tuple) of coordinates
16690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        --or: goto(vec)          # e.g. as returned by pos()
16700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Move turtle to an absolute position. If the pen is down,
16720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        a line will be drawn. The turtle's orientation does not change.
16730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
16750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> tp = turtle.pos()
16760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> tp
16770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (0.00, 0.00)
16780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.setpos(60,30)
16790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pos()
16800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (60.00,30.00)
16810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.setpos((20,80))
16820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pos()
16830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (20.00,80.00)
16840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.setpos(tp)
16850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pos()
16860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (0.00,0.00)
16870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
16880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if y is None:
16890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._goto(Vec2D(*x))
16900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
16910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._goto(Vec2D(x, y))
16920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def home(self):
16940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Move turtle to the origin - coordinates (0,0).
16950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No arguments.
16970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
16980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Move turtle to the origin - coordinates (0,0) and set its
16990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        heading to its start-orientation (which depends on mode).
17000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
17020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.home()
17030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
17040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.goto(0, 0)
17050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.setheading(0)
17060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def setx(self, x):
17080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set the turtle's first coordinate to x
17090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Argument:
17110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        x -- a number (integer or float)
17120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Set the turtle's first coordinate to x, leave second coordinate
17140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        unchanged.
17150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
17170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.position()
17180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (0.00, 240.00)
17190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.setx(10)
17200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.position()
17210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (10.00, 240.00)
17220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
17230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._goto(Vec2D(x, self._position[1]))
17240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def sety(self, y):
17260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set the turtle's second coordinate to y
17270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Argument:
17290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        y -- a number (integer or float)
17300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Set the turtle's first coordinate to x, second coordinate remains
17320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        unchanged.
17330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
17350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.position()
17360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (0.00, 40.00)
17370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.sety(-10)
17380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.position()
17390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (0.00, -10.00)
17400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
17410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._goto(Vec2D(self._position[0], y))
17420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def distance(self, x, y=None):
17440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return the distance from the turtle to (x,y) in turtle step units.
17450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
17470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        x -- a number   or  a pair/vector of numbers   or   a turtle instance
17480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        y -- a number       None                            None
17490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        call: distance(x, y)         # two coordinates
17510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        --or: distance((x, y))       # a pair (tuple) of coordinates
17520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        --or: distance(vec)          # e.g. as returned by pos()
17530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        --or: distance(mypen)        # where mypen is another turtle
17540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
17560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pos()
17570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (0.00, 0.00)
17580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.distance(30,40)
17590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        50.0
17600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> pen = Turtle()
17610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> pen.forward(77)
17620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.distance(pen)
17630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        77.0
17640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
17650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if y is not None:
17660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pos = Vec2D(x, y)
17670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(x, Vec2D):
17680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pos = x
17690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif isinstance(x, tuple):
17700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pos = Vec2D(*x)
17710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif isinstance(x, TNavigator):
17720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pos = x._position
17730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return abs(pos - self._position)
17740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def towards(self, x, y=None):
17760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return the angle of the line from the turtle's position to (x, y).
17770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
17790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        x -- a number   or  a pair/vector of numbers   or   a turtle instance
17800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        y -- a number       None                            None
17810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        call: distance(x, y)         # two coordinates
17830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        --or: distance((x, y))       # a pair (tuple) of coordinates
17840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        --or: distance(vec)          # e.g. as returned by pos()
17850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        --or: distance(mypen)        # where mypen is another turtle
17860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Return the angle, between the line from turtle-position to position
17880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        specified by x, y and the turtle's start orientation. (Depends on
17890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        modes - "standard" or "logo")
17900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
17910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
17920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pos()
17930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (10.00, 10.00)
17940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.towards(0,0)
17950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        225.0
17960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
17970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if y is not None:
17980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pos = Vec2D(x, y)
17990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(x, Vec2D):
18000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pos = x
18010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif isinstance(x, tuple):
18020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pos = Vec2D(*x)
18030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif isinstance(x, TNavigator):
18040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pos = x._position
18050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        x, y = pos - self._position
18060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0
18070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        result /= self._degreesPerAU
18080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return (self._angleOffset + self._angleOrient*result) % self._fullcircle
18090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
18100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def heading(self):
18110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Return the turtle's current heading.
18120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
18130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No arguments.
18140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
18150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
18160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.left(67)
18170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.heading()
18180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        67.0
18190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
18200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        x, y = self._orient
18210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0
18220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        result /= self._degreesPerAU
18230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return (self._angleOffset + self._angleOrient*result) % self._fullcircle
18240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
18250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def setheading(self, to_angle):
18260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set the orientation of the turtle to to_angle.
18270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
18280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Aliases:  setheading | seth
18290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
18300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Argument:
18310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        to_angle -- a number (integer or float)
18320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
18330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Set the orientation of the turtle to to_angle.
18340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Here are some common directions in degrees:
18350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
18360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         standard - mode:          logo-mode:
18370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        -------------------|--------------------
18380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           0 - east                0 - north
18390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          90 - north              90 - east
18400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         180 - west              180 - south
18410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi         270 - south             270 - west
18420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
18430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
18440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.setheading(90)
18450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.heading()
18460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        90
18470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
18480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        angle = (to_angle - self.heading())*self._angleOrient
18490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        full = self._fullcircle
18500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        angle = (angle+full/2.)%full - full/2.
18510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._rotate(angle)
18520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
18530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def circle(self, radius, extent = None, steps = None):
18540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Draw a circle with given radius.
18550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
18560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
18570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        radius -- a number
18580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        extent (optional) -- a number
18590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        steps (optional) -- an integer
18600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
18610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Draw a circle with given radius. The center is radius units left
18620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        of the turtle; extent - an angle - determines which part of the
18630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        circle is drawn. If extent is not given, draw the entire circle.
18640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If extent is not a full circle, one endpoint of the arc is the
18650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        current pen position. Draw the arc in counterclockwise direction
18660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if radius is positive, otherwise in clockwise direction. Finally
18670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        the direction of the turtle is changed by the amount of extent.
18680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
18690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        As the circle is approximated by an inscribed regular polygon,
18700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        steps determines the number of steps to use. If not given,
18710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        it will be calculated automatically. Maybe used to draw regular
18720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        polygons.
18730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
18740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        call: circle(radius)                  # full circle
18750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        --or: circle(radius, extent)          # arc
18760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        --or: circle(radius, extent, steps)
18770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        --or: circle(radius, steps=6)         # 6-sided polygon
18780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
18790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
18800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.circle(50)
18810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.circle(120, 180)  # semicircle
18820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
18830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.undobuffer:
18840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.undobuffer.push(["seq"])
18850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.undobuffer.cumulate = True
18860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        speed = self.speed()
18870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if extent is None:
18880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            extent = self._fullcircle
18890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if steps is None:
18900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            frac = abs(extent)/self._fullcircle
18910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
18920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        w = 1.0 * extent / steps
18930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        w2 = 0.5 * w
18940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        l = 2.0 * radius * math.sin(w2*math.pi/180.0*self._degreesPerAU)
18950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if radius < 0:
18960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            l, w, w2 = -l, -w, -w2
18970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tr = self.tracer()
18980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        dl = self._delay()
18990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if speed == 0:
19000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.tracer(0, 0)
19010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
19020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.speed(0)
19030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._rotate(w2)
19040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for i in range(steps):
19050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.speed(speed)
19060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._go(l)
19070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.speed(0)
19080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._rotate(w)
19090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._rotate(-w2)
19100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if speed == 0:
19110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.tracer(tr, dl)
19120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.speed(speed)
19130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.undobuffer:
19140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.undobuffer.cumulate = False
19150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## three dummy methods to be implemented by child class:
19170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def speed(self, s=0):
19190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """dummy method - to be overwritten by child class"""
19200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def tracer(self, a=None, b=None):
19210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """dummy method - to be overwritten by child class"""
19220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _delay(self, n=None):
19230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """dummy method - to be overwritten by child class"""
19240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    fd = forward
19260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    bk = back
19270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    backward = back
19280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    rt = right
19290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    lt = left
19300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    position = pos
19310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    setpos = goto
19320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    setposition = goto
19330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    seth = setheading
19340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TPen(object):
19370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Drawing part of the RawTurtle.
19380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Implements drawing properties.
19390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
19400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, resizemode=_CFG["resizemode"]):
19410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._resizemode = resizemode # or "user" or "noresize"
19420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.undobuffer = None
19430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        TPen._reset(self)
19440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _reset(self, pencolor=_CFG["pencolor"],
19460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                     fillcolor=_CFG["fillcolor"]):
19470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._pensize = 1
19480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._shown = True
19490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._pencolor = pencolor
19500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._fillcolor = fillcolor
19510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._drawing = True
19520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._speed = 3
19530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._stretchfactor = (1, 1)
19540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._tilt = 0
19550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._outlinewidth = 1
19560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ### self.screen = None  # to override by child class
19570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def resizemode(self, rmode=None):
19590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set resizemode to one of the values: "auto", "user", "noresize".
19600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (Optional) Argument:
19620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        rmode -- one of the strings "auto", "user", "noresize"
19630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Different resizemodes have the following effects:
19650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          - "auto" adapts the appearance of the turtle
19660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                   corresponding to the value of pensize.
19670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          - "user" adapts the appearance of the turtle according to the
19680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                   values of stretchfactor and outlinewidth (outline),
19690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                   which are set by shapesize()
19700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          - "noresize" no adaption of the turtle's appearance takes place.
19710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If no argument is given, return current resizemode.
19720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        resizemode("user") is called by a call of shapesize with arguments.
19730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Examples (for a Turtle instance named turtle):
19760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.resizemode("noresize")
19770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.resizemode()
19780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'noresize'
19790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
19800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if rmode is None:
19810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self._resizemode
19820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        rmode = rmode.lower()
19830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if rmode in ["auto", "user", "noresize"]:
19840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.pen(resizemode=rmode)
19850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def pensize(self, width=None):
19870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set or return the line thickness.
19880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Aliases:  pensize | width
19900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Argument:
19920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        width -- positive number
19930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Set the line thickness to width or return it. If resizemode is set
19950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        to "auto" and turtleshape is a polygon, that polygon is drawn with
19960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        the same line thickness. If no argument is given, current pensize
19970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        is returned.
19980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
19990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
20000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pensize()
20010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        1
20020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pensize(10)   # from here on lines of width 10 are drawn
20030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
20040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if width is None:
20050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self._pensize
20060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.pen(pensize=width)
20070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def penup(self):
20100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Pull the pen up -- no drawing when moving.
20110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Aliases: penup | pu | up
20130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument
20150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
20170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.penup()
20180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
20190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if not self._drawing:
20200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return
20210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.pen(pendown=False)
20220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def pendown(self):
20240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Pull the pen down -- drawing when moving.
20250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Aliases: pendown | pd | down
20270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
20290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
20310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pendown()
20320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
20330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._drawing:
20340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return
20350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.pen(pendown=True)
20360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def isdown(self):
20380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return True if pen is down, False if it's up.
20390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
20410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
20430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.penup()
20440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.isdown()
20450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        False
20460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pendown()
20470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.isdown()
20480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        True
20490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
20500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self._drawing
20510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def speed(self, speed=None):
20530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Return or set the turtle's speed.
20540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Optional argument:
20560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        speed -- an integer in the range 0..10 or a speedstring (see below)
20570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Set the turtle's speed to an integer value in the range 0 .. 10.
20590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If no argument is given: return current speed.
20600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If input is a number greater than 10 or smaller than 0.5,
20620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        speed is set to 0.
20630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Speedstrings  are mapped to speedvalues in the following way:
20640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'fastest' :  0
20650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'fast'    :  10
20660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'normal'  :  6
20670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'slow'    :  3
20680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            'slowest' :  1
20690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        speeds from 1 to 10 enforce increasingly faster animation of
20700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        line drawing and turtle turning.
20710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Attention:
20730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        speed = 0 : *no* animation takes place. forward/back makes turtle jump
20740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        and likewise left/right make the turtle turn instantly.
20750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
20770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.speed(3)
20780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
20790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        speeds = {'fastest':0, 'fast':10, 'normal':6, 'slow':3, 'slowest':1 }
20800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if speed is None:
20810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self._speed
20820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if speed in speeds:
20830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            speed = speeds[speed]
20840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif 0.5 < speed < 10.5:
20850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            speed = int(round(speed))
20860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
20870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            speed = 0
20880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.pen(speed=speed)
20890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def color(self, *args):
20910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return or set the pencolor and fillcolor.
20920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
20940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Several input formats are allowed.
20950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        They use 0, 1, 2, or 3 arguments as follows:
20960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
20970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        color()
20980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            Return the current pencolor and the current fillcolor
20990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            as a pair of color specification strings as are returned
21000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            by pencolor and fillcolor.
21010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        color(colorstring), color((r,g,b)), color(r,g,b)
21020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            inputs as in pencolor, set both, fillcolor and pencolor,
21030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            to the given value.
21040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        color(colorstring1, colorstring2),
21050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        color((r1,g1,b1), (r2,g2,b2))
21060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            equivalent to pencolor(colorstring1) and fillcolor(colorstring2)
21070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            and analogously, if the other input format is used.
21080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
21090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If turtleshape is a polygon, outline and interior of that polygon
21100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        is drawn with the newly set colors.
21110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        For mor info see: pencolor, fillcolor
21120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
21130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
21140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.color('red', 'green')
21150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.color()
21160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ('red', 'green')
21170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> colormode(255)
21180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> color((40, 80, 120), (160, 200, 240))
21190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> color()
21200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ('#285078', '#a0c8f0')
21210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
21220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if args:
21230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            l = len(args)
21240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if l == 1:
21250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pcolor = fcolor = args[0]
21260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            elif l == 2:
21270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pcolor, fcolor = args
21280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            elif l == 3:
21290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                pcolor = fcolor = args
21300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pcolor = self._colorstr(pcolor)
21310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            fcolor = self._colorstr(fcolor)
21320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.pen(pencolor=pcolor, fillcolor=fcolor)
21330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
21340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self._color(self._pencolor), self._color(self._fillcolor)
21350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
21360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def pencolor(self, *args):
21370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Return or set the pencolor.
21380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
21390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
21400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Four input formats are allowed:
21410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          - pencolor()
21420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            Return the current pencolor as color specification string,
21430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            possibly in hex-number format (see example).
21440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            May be used as input to another color/pencolor/fillcolor call.
21450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          - pencolor(colorstring)
21460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            s is a Tk color specification string, such as "red" or "yellow"
21470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          - pencolor((r, g, b))
21480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            *a tuple* of r, g, and b, which represent, an RGB color,
21490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            and each of r, g, and b are in the range 0..colormode,
21500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            where colormode is either 1.0 or 255
21510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          - pencolor(r, g, b)
21520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            r, g, and b represent an RGB color, and each of r, g, and b
21530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            are in the range 0..colormode
21540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
21550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If turtleshape is a polygon, the outline of that polygon is drawn
21560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with the newly set pencolor.
21570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
21580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
21590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pencolor('brown')
21600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> tup = (0.2, 0.8, 0.55)
21610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pencolor(tup)
21620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pencolor()
21630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        '#33cc8c'
21640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
21650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if args:
21660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            color = self._colorstr(args)
21670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if color == self._pencolor:
21680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                return
21690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.pen(pencolor=color)
21700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
21710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self._color(self._pencolor)
21720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
21730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def fillcolor(self, *args):
21740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Return or set the fillcolor.
21750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
21760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
21770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Four input formats are allowed:
21780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          - fillcolor()
21790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            Return the current fillcolor as color specification string,
21800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            possibly in hex-number format (see example).
21810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            May be used as input to another color/pencolor/fillcolor call.
21820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          - fillcolor(colorstring)
21830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            s is a Tk color specification string, such as "red" or "yellow"
21840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          - fillcolor((r, g, b))
21850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            *a tuple* of r, g, and b, which represent, an RGB color,
21860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            and each of r, g, and b are in the range 0..colormode,
21870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            where colormode is either 1.0 or 255
21880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          - fillcolor(r, g, b)
21890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            r, g, and b represent an RGB color, and each of r, g, and b
21900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            are in the range 0..colormode
21910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
21920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If turtleshape is a polygon, the interior of that polygon is drawn
21930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with the newly set fillcolor.
21940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
21950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
21960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.fillcolor('violet')
21970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> col = turtle.pencolor()
21980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.fillcolor(col)
21990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.fillcolor(0, .5, 0)
22000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
22010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if args:
22020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            color = self._colorstr(args)
22030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if color == self._fillcolor:
22040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                return
22050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.pen(fillcolor=color)
22060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
22070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self._color(self._fillcolor)
22080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def showturtle(self):
22100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Makes the turtle visible.
22110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Aliases: showturtle | st
22130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
22150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
22170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.hideturtle()
22180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.showturtle()
22190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
22200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.pen(shown=True)
22210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def hideturtle(self):
22230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Makes the turtle invisible.
22240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Aliases: hideturtle | ht
22260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
22280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        It's a good idea to do this while you're in the
22300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        middle of a complicated drawing, because hiding
22310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        the turtle speeds up the drawing observably.
22320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
22340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.hideturtle()
22350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
22360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.pen(shown=False)
22370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def isvisible(self):
22390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return True if the Turtle is shown, False if it's hidden.
22400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
22420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
22440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.hideturtle()
22450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> print turtle.isvisible():
22460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        False
22470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
22480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self._shown
22490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def pen(self, pen=None, **pendict):
22510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return or set the pen's attributes.
22520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
22540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pen -- a dictionary with some or all of the below listed keys.
22550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            **pendict -- one or more keyword-arguments with the below
22560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                         listed keys as keywords.
22570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Return or set the pen's attributes in a 'pen-dictionary'
22590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        with the following key/value pairs:
22600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           "shown"      :   True/False
22610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           "pendown"    :   True/False
22620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           "pencolor"   :   color-string or color-tuple
22630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           "fillcolor"  :   color-string or color-tuple
22640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           "pensize"    :   positive number
22650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           "speed"      :   number in range 0..10
22660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           "resizemode" :   "auto" or "user" or "noresize"
22670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           "stretchfactor": (positive number, positive number)
22680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           "outline"    :   positive number
22690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           "tilt"       :   number
22700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        This dictionary can be used as argument for a subsequent
22720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pen()-call to restore the former pen-state. Moreover one
22730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        or more of these attributes can be provided as keyword-arguments.
22740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        This can be used to set several pen attributes in one statement.
22750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
22770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Examples (for a Turtle instance named turtle):
22780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10)
22790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pen()
22800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
22810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'pencolor': 'red', 'pendown': True, 'fillcolor': 'black',
22820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'stretchfactor': (1,1), 'speed': 3}
22830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> penstate=turtle.pen()
22840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.color("yellow","")
22850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.penup()
22860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.pen()
22870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
22880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'pencolor': 'yellow', 'pendown': False, 'fillcolor': '',
22890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'stretchfactor': (1,1), 'speed': 3}
22900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> p.pen(penstate, fillcolor="green")
22910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> p.pen()
22920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
22930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'pencolor': 'red', 'pendown': True, 'fillcolor': 'green',
22940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'stretchfactor': (1,1), 'speed': 3}
22950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
22960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        _pd =  {"shown"         : self._shown,
22970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                "pendown"       : self._drawing,
22980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                "pencolor"      : self._pencolor,
22990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                "fillcolor"     : self._fillcolor,
23000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                "pensize"       : self._pensize,
23010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                "speed"         : self._speed,
23020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                "resizemode"    : self._resizemode,
23030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                "stretchfactor" : self._stretchfactor,
23040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                "outline"       : self._outlinewidth,
23050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                "tilt"          : self._tilt
23060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi               }
23070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
23080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if not (pen or pendict):
23090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return _pd
23100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
23110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(pen, dict):
23120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            p = pen
23130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
23140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            p = {}
23150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        p.update(pendict)
23160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
23170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        _p_buf = {}
23180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for key in p:
23190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            _p_buf[key] = _pd[key]
23200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
23210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.undobuffer:
23220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.undobuffer.push(("pen", _p_buf))
23230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
23240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        newLine = False
23250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if "pendown" in p:
23260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self._drawing != p["pendown"]:
23270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                newLine = True
23280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if "pencolor" in p:
23290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if isinstance(p["pencolor"], tuple):
23300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                p["pencolor"] = self._colorstr((p["pencolor"],))
23310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self._pencolor != p["pencolor"]:
23320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                newLine = True
23330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if "pensize" in p:
23340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self._pensize != p["pensize"]:
23350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                newLine = True
23360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if newLine:
23370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._newLine()
23380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if "pendown" in p:
23390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._drawing = p["pendown"]
23400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if "pencolor" in p:
23410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._pencolor = p["pencolor"]
23420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if "pensize" in p:
23430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._pensize = p["pensize"]
23440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if "fillcolor" in p:
23450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if isinstance(p["fillcolor"], tuple):
23460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                p["fillcolor"] = self._colorstr((p["fillcolor"],))
23470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._fillcolor = p["fillcolor"]
23480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if "speed" in p:
23490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._speed = p["speed"]
23500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if "resizemode" in p:
23510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._resizemode = p["resizemode"]
23520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if "stretchfactor" in p:
23530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            sf = p["stretchfactor"]
23540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if isinstance(sf, (int, float)):
23550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                sf = (sf, sf)
23560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._stretchfactor = sf
23570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if "outline" in p:
23580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._outlinewidth = p["outline"]
23590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if "shown" in p:
23600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._shown = p["shown"]
23610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if "tilt" in p:
23620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._tilt = p["tilt"]
23630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._update()
23640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
23650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## three dummy methods to be implemented by child class:
23660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
23670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _newLine(self, usePos = True):
23680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """dummy method - to be overwritten by child class"""
23690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _update(self, count=True, forced=False):
23700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """dummy method - to be overwritten by child class"""
23710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _color(self, args):
23720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """dummy method - to be overwritten by child class"""
23730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _colorstr(self, args):
23740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """dummy method - to be overwritten by child class"""
23750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
23760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    width = pensize
23770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    up = penup
23780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    pu = penup
23790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    pd = pendown
23800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    down = pendown
23810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    st = showturtle
23820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    ht = hideturtle
23830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
23840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
23850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass _TurtleImage(object):
23860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Helper class: Datatype to store Turtle attributes
23870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
23880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
23890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, screen, shapeIndex):
23900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.screen = screen
23910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._type = None
23920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._setshape(shapeIndex)
23930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
23940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _setshape(self, shapeIndex):
23950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        screen = self.screen # RawTurtle.screens[self.screenIndex]
23960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.shapeIndex = shapeIndex
23970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._type == "polygon" == screen._shapes[shapeIndex]._type:
23980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return
23990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._type == "image" == screen._shapes[shapeIndex]._type:
24000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return
24010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._type in ["image", "polygon"]:
24020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            screen._delete(self._item)
24030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif self._type == "compound":
24040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for item in self._item:
24050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                screen._delete(item)
24060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._type = screen._shapes[shapeIndex]._type
24070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._type == "polygon":
24080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._item = screen._createpoly()
24090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif self._type == "image":
24100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._item = screen._createimage(screen._shapes["blank"]._data)
24110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif self._type == "compound":
24120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._item = [screen._createpoly() for item in
24130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                          screen._shapes[shapeIndex]._data]
24140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
24150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
24160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass RawTurtle(TPen, TNavigator):
24170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Animation part of the RawTurtle.
24180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Puts RawTurtle upon a TurtleScreen and provides tools for
24190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    its animation.
24200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
24210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    screens = []
24220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
24230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self, canvas=None,
24240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                 shape=_CFG["shape"],
24250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                 undobuffersize=_CFG["undobuffersize"],
24260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                 visible=_CFG["visible"]):
24270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(canvas, _Screen):
24280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.screen = canvas
24290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif isinstance(canvas, TurtleScreen):
24300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if canvas not in RawTurtle.screens:
24310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                RawTurtle.screens.append(canvas)
24320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.screen = canvas
24330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif isinstance(canvas, (ScrolledCanvas, Canvas)):
24340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for screen in RawTurtle.screens:
24350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if screen.cv == canvas:
24360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.screen = screen
24370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    break
24380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
24390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.screen = TurtleScreen(canvas)
24400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                RawTurtle.screens.append(self.screen)
24410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
24420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            raise TurtleGraphicsError("bad cavas argument %s" % canvas)
24430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
24440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        screen = self.screen
24450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        TNavigator.__init__(self, screen.mode())
24460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        TPen.__init__(self)
24470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        screen._turtles.append(self)
24480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.drawingLineItem = screen._createline()
24490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.turtle = _TurtleImage(screen, shape)
24500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._poly = None
24510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._creatingPoly = False
24520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._fillitem = self._fillpath = None
24530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._shown = visible
24540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._hidden_from_screen = False
24550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.currentLineItem = screen._createline()
24560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.currentLine = [self._position]
24570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.items = [self.currentLineItem]
24580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.stampItems = []
24590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._undobuffersize = undobuffersize
24600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.undobuffer = Tbuffer(undobuffersize)
24610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._update()
24620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
24630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def reset(self):
24640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Delete the turtle's drawings and restore its default values.
24650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
24660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
24670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi,
24680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Delete the turtle's drawings from the screen, re-center the turtle
24690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        and set variables to the default values.
24700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
24710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
24720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.position()
24730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (0.00,-22.00)
24740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.heading()
24750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        100.0
24760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.reset()
24770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.position()
24780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (0.00,0.00)
24790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.heading()
24800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        0.0
24810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
24820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        TNavigator.reset(self)
24830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        TPen._reset(self)
24840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._clear()
24850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._drawturtle()
24860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._update()
24870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
24880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def setundobuffer(self, size):
24890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set or disable undobuffer.
24900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
24910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Argument:
24920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        size -- an integer or None
24930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
24940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If size is an integer an empty undobuffer of given size is installed.
24950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Size gives the maximum number of turtle-actions that can be undone
24960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        by the undo() function.
24970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If size is None, no undobuffer is present.
24980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
24990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
25000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.setundobuffer(42)
25010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
25020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if size is None:
25030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.undobuffer = None
25040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
25050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.undobuffer = Tbuffer(size)
25060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def undobufferentries(self):
25080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return count of entries in the undobuffer.
25090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
25110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
25130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> while undobufferentries():
25140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     undo()
25150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
25160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.undobuffer is None:
25170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return 0
25180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.undobuffer.nr_of_items()
25190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _clear(self):
25210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Delete all of pen's drawings"""
25220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._fillitem = self._fillpath = None
25230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for item in self.items:
25240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.screen._delete(item)
25250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.currentLineItem = self.screen._createline()
25260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.currentLine = []
25270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._drawing:
25280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.currentLine.append(self._position)
25290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.items = [self.currentLineItem]
25300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.clearstamps()
25310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.setundobuffer(self._undobuffersize)
25320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def clear(self):
25350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Delete the turtle's drawings from the screen. Do not move turtle.
25360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No arguments.
25380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Delete the turtle's drawings from the screen. Do not move turtle.
25400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        State and position of the turtle as well as drawings of other
25410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtles are not affected.
25420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Examples (for a Turtle instance named turtle):
25440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.clear()
25450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
25460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._clear()
25470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._update()
25480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _update_data(self):
25500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.screen._incrementudc()
25510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.screen._updatecounter != 0:
25520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return
25530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if len(self.currentLine)>1:
25540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.screen._drawline(self.currentLineItem, self.currentLine,
25550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                  self._pencolor, self._pensize)
25560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _update(self):
25580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Perform a Turtle-data update.
25590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
25600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        screen = self.screen
25610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if screen._tracing == 0:
25620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return
25630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif screen._tracing == 1:
25640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._update_data()
25650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._drawturtle()
25660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            screen._update()                  # TurtleScreenBase
25670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            screen._delay(screen._delayvalue) # TurtleScreenBase
25680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
25690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._update_data()
25700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if screen._updatecounter == 0:
25710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                for t in screen.turtles():
25720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    t._drawturtle()
25730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                screen._update()
25740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def tracer(self, flag=None, delay=None):
25760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Turns turtle animation on/off and set delay for update drawings.
25770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Optional arguments:
25790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        n -- nonnegative  integer
25800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        delay -- nonnegative  integer
25810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If n is given, only each n-th regular screen update is really performed.
25830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (Can be used to accelerate the drawing of complex graphics.)
25840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Second arguments sets delay value (see RawTurtle.delay())
25850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
25870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.tracer(8, 25)
25880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> dist = 2
25890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> for i in range(200):
25900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     turtle.fd(dist)
25910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     turtle.rt(90)
25920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     dist += 2
25930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
25940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.screen.tracer(flag, delay)
25950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _color(self, args):
25970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.screen._color(args)
25980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
25990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _colorstr(self, args):
26000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.screen._colorstr(args)
26010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _cc(self, args):
26030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Convert colortriples to hexstrings.
26040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
26050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(args, str):
26060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return args
26070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
26080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            r, g, b = args
26090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        except:
26100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            raise TurtleGraphicsError("bad color arguments: %s" % str(args))
26110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.screen._colormode == 1.0:
26120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            r, g, b = [round(255.0*x) for x in (r, g, b)]
26130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)):
26140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            raise TurtleGraphicsError("bad color sequence: %s" % str(args))
26150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return "#%02x%02x%02x" % (r, g, b)
26160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def clone(self):
26180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Create and return a clone of the turtle.
26190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
26210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Create and return a clone of the turtle with same position, heading
26230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        and turtle properties.
26240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named mick):
26260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mick = Turtle()
26270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        joe = mick.clone()
26280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
26290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        screen = self.screen
26300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._newLine(self._drawing)
26310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle = self.turtle
26330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.screen = None
26340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.turtle = None  # too make self deepcopy-able
26350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        q = deepcopy(self)
26370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.screen = screen
26390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.turtle = turtle
26400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        q.screen = screen
26420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        q.turtle = _TurtleImage(screen, self.turtle.shapeIndex)
26430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        screen._turtles.append(q)
26450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ttype = screen._shapes[self.turtle.shapeIndex]._type
26460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if ttype == "polygon":
26470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            q.turtle._item = screen._createpoly()
26480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif ttype == "image":
26490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            q.turtle._item = screen._createimage(screen._shapes["blank"]._data)
26500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif ttype == "compound":
26510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            q.turtle._item = [screen._createpoly() for item in
26520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                              screen._shapes[self.turtle.shapeIndex]._data]
26530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        q.currentLineItem = screen._createline()
26540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        q._update()
26550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return q
26560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def shape(self, name=None):
26580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set turtle shape to shape with given name / return current shapename.
26590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Optional argument:
26610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        name -- a string, which is a valid shapename
26620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Set turtle shape to shape with given name or, if name is not given,
26640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return name of current shape.
26650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Shape with name must exist in the TurtleScreen's shape dictionary.
26660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Initially there are the following polygon shapes:
26670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'arrow', 'turtle', 'circle', 'square', 'triangle', 'classic'.
26680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        To learn about how to deal with shapes see Screen-method register_shape.
26690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
26710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.shape()
26720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'arrow'
26730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.shape("turtle")
26740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.shape()
26750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        'turtle'
26760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
26770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if name is None:
26780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return self.turtle.shapeIndex
26790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if not name in self.screen.getshapes():
26800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            raise TurtleGraphicsError("There is no shape named %s" % name)
26810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.turtle._setshape(name)
26820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._update()
26830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def shapesize(self, stretch_wid=None, stretch_len=None, outline=None):
26850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set/return turtle's stretchfactors/outline. Set resizemode to "user".
26860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Optinonal arguments:
26880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           stretch_wid : positive number
26890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           stretch_len : positive number
26900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           outline  : positive number
26910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
26920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Return or set the pen's attributes x/y-stretchfactors and/or outline.
26930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Set resizemode to "user".
26940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If and only if resizemode is set to "user", the turtle will be displayed
26950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        stretched according to its stretchfactors:
26960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        stretch_wid is stretchfactor perpendicular to orientation
26970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        stretch_len is stretchfactor in direction of turtles orientation.
26980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        outline determines the width of the shapes's outline.
26990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Examples (for a Turtle instance named turtle):
27010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.resizemode("user")
27020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.shapesize(5, 5, 12)
27030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.shapesize(outline=8)
27040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
27050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if stretch_wid is stretch_len is outline is None:
27060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            stretch_wid, stretch_len = self._stretchfactor
27070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return stretch_wid, stretch_len, self._outlinewidth
27080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if stretch_wid is not None:
27090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if stretch_len is None:
27100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                stretchfactor = stretch_wid, stretch_wid
27110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
27120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                stretchfactor = stretch_wid, stretch_len
27130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif stretch_len is not None:
27140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            stretchfactor = self._stretchfactor[0], stretch_len
27150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
27160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            stretchfactor = self._stretchfactor
27170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if outline is None:
27180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            outline = self._outlinewidth
27190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.pen(resizemode="user",
27200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                 stretchfactor=stretchfactor, outline=outline)
27210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def settiltangle(self, angle):
27230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Rotate the turtleshape to point in the specified direction
27240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Optional argument:
27260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        angle -- number
27270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Rotate the turtleshape to point in the direction specified by angle,
27290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        regardless of its current tilt-angle. DO NOT change the turtle's
27300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        heading (direction of movement).
27310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Examples (for a Turtle instance named turtle):
27340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.shape("circle")
27350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.shapesize(5,2)
27360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.settiltangle(45)
27370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> stamp()
27380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.fd(50)
27390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.settiltangle(-45)
27400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> stamp()
27410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.fd(50)
27420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
27430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tilt = -angle * self._degreesPerAU * self._angleOrient
27440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tilt = (tilt * math.pi / 180.0) % (2*math.pi)
27450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.pen(resizemode="user", tilt=tilt)
27460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def tiltangle(self):
27480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return the current tilt-angle.
27490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
27510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Return the current tilt-angle, i. e. the angle between the
27530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        orientation of the turtleshape and the heading of the turtle
27540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (its direction of movement).
27550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Examples (for a Turtle instance named turtle):
27570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.shape("circle")
27580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.shapesize(5,2)
27590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.tilt(45)
27600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.tiltangle()
27610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
27620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tilt = -self._tilt * (180.0/math.pi) * self._angleOrient
27630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return (tilt / self._degreesPerAU) % self._fullcircle
27640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def tilt(self, angle):
27660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Rotate the turtleshape by angle.
27670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Argument:
27690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        angle - a number
27700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Rotate the turtleshape by angle from its current tilt-angle,
27720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        but do NOT change the turtle's heading (direction of movement).
27730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Examples (for a Turtle instance named turtle):
27750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.shape("circle")
27760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.shapesize(5,2)
27770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.tilt(30)
27780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.fd(50)
27790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.tilt(30)
27800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.fd(50)
27810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
27820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.settiltangle(angle + self.tiltangle())
27830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _polytrafo(self, poly):
27850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Computes transformed polygon shapes from a shape
27860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        according to current position and heading.
27870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
27880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        screen = self.screen
27890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        p0, p1 = self._position
27900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        e0, e1 = self._orient
27910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        e = Vec2D(e0, e1 * screen.yscale / screen.xscale)
27920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        e0, e1 = (1.0 / abs(e)) * e
27930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return [(p0+(e1*x+e0*y)/screen.xscale, p1+(-e0*x+e1*y)/screen.yscale)
27940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                                           for (x, y) in poly]
27950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
27960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _drawturtle(self):
27970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Manages the correct rendering of the turtle with respect to
27980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        its shape, resizemode, stretch and tilt etc."""
27990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        screen = self.screen
28000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        shape = screen._shapes[self.turtle.shapeIndex]
28010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ttype = shape._type
28020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        titem = self.turtle._item
28030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._shown and screen._updatecounter == 0 and screen._tracing > 0:
28040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._hidden_from_screen = False
28050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            tshape = shape._data
28060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if ttype == "polygon":
28070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if self._resizemode == "noresize":
28080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    w = 1
28090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    shape = tshape
28100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                else:
28110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    if self._resizemode == "auto":
28120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        lx = ly = max(1, self._pensize/5.0)
28130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        w = self._pensize
28140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        tiltangle = 0
28150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    elif self._resizemode == "user":
28160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        lx, ly = self._stretchfactor
28170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        w = self._outlinewidth
28180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        tiltangle = self._tilt
28190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    shape = [(lx*x, ly*y) for (x, y) in tshape]
28200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    t0, t1 = math.sin(tiltangle), math.cos(tiltangle)
28210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    shape = [(t1*x+t0*y, -t0*x+t1*y) for (x, y) in shape]
28220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                shape = self._polytrafo(shape)
28230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                fc, oc = self._fillcolor, self._pencolor
28240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                screen._drawpoly(titem, shape, fill=fc, outline=oc,
28250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                                      width=w, top=True)
28260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            elif ttype == "image":
28270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                screen._drawimage(titem, self._position, tshape)
28280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            elif ttype == "compound":
28290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                lx, ly = self._stretchfactor
28300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                w = self._outlinewidth
28310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                for item, (poly, fc, oc) in zip(titem, tshape):
28320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    poly = [(lx*x, ly*y) for (x, y) in poly]
28330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    poly = self._polytrafo(poly)
28340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    screen._drawpoly(item, poly, fill=self._cc(fc),
28350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                     outline=self._cc(oc), width=w, top=True)
28360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
28370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self._hidden_from_screen:
28380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                return
28390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if ttype == "polygon":
28400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                screen._drawpoly(titem, ((0, 0), (0, 0), (0, 0)), "", "")
28410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            elif ttype == "image":
28420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                screen._drawimage(titem, self._position,
28430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                          screen._shapes["blank"]._data)
28440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            elif ttype == "compound":
28450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                for item in titem:
28460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    screen._drawpoly(item, ((0, 0), (0, 0), (0, 0)), "", "")
28470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._hidden_from_screen = True
28480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
28490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi##############################  stamp stuff  ###############################
28500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
28510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def stamp(self):
28520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Stamp a copy of the turtleshape onto the canvas and return its id.
28530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
28540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
28550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
28560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Stamp a copy of the turtle shape onto the canvas at the current
28570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle position. Return a stamp_id for that stamp, which can be
28580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        used to delete it by calling clearstamp(stamp_id).
28590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
28600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
28610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.color("blue")
28620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.stamp()
28630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        13
28640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.fd(50)
28650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
28660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        screen = self.screen
28670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        shape = screen._shapes[self.turtle.shapeIndex]
28680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ttype = shape._type
28690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tshape = shape._data
28700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if ttype == "polygon":
28710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            stitem = screen._createpoly()
28720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self._resizemode == "noresize":
28730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                w = 1
28740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                shape = tshape
28750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
28760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if self._resizemode == "auto":
28770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    lx = ly = max(1, self._pensize/5.0)
28780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    w = self._pensize
28790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    tiltangle = 0
28800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                elif self._resizemode == "user":
28810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    lx, ly = self._stretchfactor
28820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    w = self._outlinewidth
28830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    tiltangle = self._tilt
28840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                shape = [(lx*x, ly*y) for (x, y) in tshape]
28850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                t0, t1 = math.sin(tiltangle), math.cos(tiltangle)
28860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                shape = [(t1*x+t0*y, -t0*x+t1*y) for (x, y) in shape]
28870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            shape = self._polytrafo(shape)
28880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            fc, oc = self._fillcolor, self._pencolor
28890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            screen._drawpoly(stitem, shape, fill=fc, outline=oc,
28900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                                  width=w, top=True)
28910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif ttype == "image":
28920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            stitem = screen._createimage("")
28930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            screen._drawimage(stitem, self._position, tshape)
28940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif ttype == "compound":
28950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            stitem = []
28960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for element in tshape:
28970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                item = screen._createpoly()
28980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                stitem.append(item)
28990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            stitem = tuple(stitem)
29000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            lx, ly = self._stretchfactor
29010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            w = self._outlinewidth
29020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for item, (poly, fc, oc) in zip(stitem, tshape):
29030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                poly = [(lx*x, ly*y) for (x, y) in poly]
29040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                poly = self._polytrafo(poly)
29050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                screen._drawpoly(item, poly, fill=self._cc(fc),
29060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                 outline=self._cc(oc), width=w, top=True)
29070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.stampItems.append(stitem)
29080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.undobuffer.push(("stamp", stitem))
29090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return stitem
29100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
29110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _clearstamp(self, stampid):
29120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """does the work for clearstamp() and clearstamps()
29130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
29140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if stampid in self.stampItems:
29150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if isinstance(stampid, tuple):
29160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                for subitem in stampid:
29170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.screen._delete(subitem)
29180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
29190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.screen._delete(stampid)
29200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.stampItems.remove(stampid)
29210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Delete stampitem from undobuffer if necessary
29220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # if clearstamp is called directly.
29230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        item = ("stamp", stampid)
29240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        buf = self.undobuffer
29250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if item not in buf.buffer:
29260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return
29270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        index = buf.buffer.index(item)
29280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        buf.buffer.remove(item)
29290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if index <= buf.ptr:
29300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            buf.ptr = (buf.ptr - 1) % buf.bufsize
29310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        buf.buffer.insert((buf.ptr+1)%buf.bufsize, [None])
29320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
29330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def clearstamp(self, stampid):
29340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Delete stamp with given stampid
29350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
29360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Argument:
29370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        stampid - an integer, must be return value of previous stamp() call.
29380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
29390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
29400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.color("blue")
29410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> astamp = turtle.stamp()
29420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.fd(50)
29430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.clearstamp(astamp)
29440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
29450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._clearstamp(stampid)
29460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._update()
29470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
29480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def clearstamps(self, n=None):
29490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Delete all or first/last n of turtle's stamps.
29500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
29510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Optional argument:
29520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        n -- an integer
29530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
29540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If n is None, delete all of pen's stamps,
29550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else if n > 0 delete first n stamps
29560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else if n < 0 delete last n stamps.
29570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
29580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
29590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> for i in range(8):
29600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     turtle.stamp(); turtle.fd(30)
29610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...
29620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.clearstamps(2)
29630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.clearstamps(-2)
29640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.clearstamps()
29650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
29660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if n is None:
29670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            toDelete = self.stampItems[:]
29680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif n >= 0:
29690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            toDelete = self.stampItems[:n]
29700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
29710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            toDelete = self.stampItems[n:]
29720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for item in toDelete:
29730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._clearstamp(item)
29740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._update()
29750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
29760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _goto(self, end):
29770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Move the pen to the point end, thereby drawing a line
29780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if pen is down. All other methodes for turtle movement depend
29790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        on this one.
29800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
29810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ## Version mit undo-stuff
29820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        go_modes = ( self._drawing,
29830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                     self._pencolor,
29840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                     self._pensize,
29850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                     isinstance(self._fillpath, list))
29860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        screen = self.screen
29870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        undo_entry = ("go", self._position, end, go_modes,
29880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      (self.currentLineItem,
29890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      self.currentLine[:],
29900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      screen._pointlist(self.currentLineItem),
29910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      self.items[:])
29920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                      )
29930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.undobuffer:
29940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.undobuffer.push(undo_entry)
29950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        start = self._position
29960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._speed and screen._tracing == 1:
29970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            diff = (end-start)
29980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2
29990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
30000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            delta = diff * (1.0/nhops)
30010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for n in range(1, nhops):
30020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if n == 1:
30030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    top = True
30040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                else:
30050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    top = False
30060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self._position = start + delta * n
30070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if self._drawing:
30080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    screen._drawline(self.drawingLineItem,
30090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                     (start, self._position),
30100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                     self._pencolor, self._pensize, top)
30110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self._update()
30120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self._drawing:
30130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
30140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                               fill="", width=self._pensize)
30150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Turtle now at end,
30160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._drawing: # now update currentLine
30170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.currentLine.append(end)
30180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(self._fillpath, list):
30190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._fillpath.append(end)
30200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ######    vererbung!!!!!!!!!!!!!!!!!!!!!!
30210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._position = end
30220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._creatingPoly:
30230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._poly.append(end)
30240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if len(self.currentLine) > 42: # 42! answer to the ultimate question
30250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                       # of life, the universe and everything
30260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._newLine()
30270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._update() #count=True)
30280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
30290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _undogoto(self, entry):
30300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Reverse a _goto. Used for undo()
30310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
30320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        old, new, go_modes, coodata = entry
30330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        drawing, pc, ps, filling = go_modes
30340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        cLI, cL, pl, items = coodata
30350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        screen = self.screen
30360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if abs(self._position - new) > 0.5:
30370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            print "undogoto: HALLO-DA-STIMMT-WAS-NICHT!"
30380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # restore former situation
30390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.currentLineItem = cLI
30400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.currentLine = cL
30410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
30420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if pl == [(0, 0), (0, 0)]:
30430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            usepc = ""
30440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
30450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            usepc = pc
30460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        screen._drawline(cLI, pl, fill=usepc, width=ps)
30470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
30480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        todelete = [i for i in self.items if (i not in items) and
30490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                       (screen._type(i) == "line")]
30500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for i in todelete:
30510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            screen._delete(i)
30520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.items.remove(i)
30530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
30540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        start = old
30550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._speed and screen._tracing == 1:
30560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            diff = old - new
30570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2
30580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
30590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            delta = diff * (1.0/nhops)
30600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for n in range(1, nhops):
30610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if n == 1:
30620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    top = True
30630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                else:
30640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    top = False
30650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self._position = new + delta * n
30660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if drawing:
30670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    screen._drawline(self.drawingLineItem,
30680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                     (start, self._position),
30690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                     pc, ps, top)
30700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self._update()
30710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if drawing:
30720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
30730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                               fill="", width=ps)
30740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # Turtle now at position old,
30750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._position = old
30760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ##  if undo is done during creating a polygon, the last vertex
30770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ##  will be deleted. if the polygon is entirely deleted,
30780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ##  creatingPoly will be set to False.
30790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ##  Polygons created before the last one will not be affected by undo()
30800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._creatingPoly:
30810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if len(self._poly) > 0:
30820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self._poly.pop()
30830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self._poly == []:
30840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self._creatingPoly = False
30850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self._poly = None
30860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if filling:
30870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self._fillpath == []:
30880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self._fillpath = None
30890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                print "Unwahrscheinlich in _undogoto!"
30900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            elif self._fillpath is not None:
30910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self._fillpath.pop()
30920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._update() #count=True)
30930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
30940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _rotate(self, angle):
30950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Turns pen clockwise by angle.
30960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
30970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.undobuffer:
30980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.undobuffer.push(("rot", angle, self._degreesPerAU))
30990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        angle *= self._degreesPerAU
31000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        neworient = self._orient.rotate(angle)
31010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tracing = self.screen._tracing
31020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if tracing == 1 and self._speed > 0:
31030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            anglevel = 3.0 * self._speed
31040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            steps = 1 + int(abs(angle)/anglevel)
31050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            delta = 1.0*angle/steps
31060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for _ in range(steps):
31070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self._orient = self._orient.rotate(delta)
31080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self._update()
31090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._orient = neworient
31100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._update()
31110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
31120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _newLine(self, usePos=True):
31130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Closes current line item and starts a new one.
31140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           Remark: if current line became too long, animation
31150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi           performance (via _drawline) slowed down considerably.
31160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
31170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if len(self.currentLine) > 1:
31180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.screen._drawline(self.currentLineItem, self.currentLine,
31190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                      self._pencolor, self._pensize)
31200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.currentLineItem = self.screen._createline()
31210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.items.append(self.currentLineItem)
31220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
31230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.screen._drawline(self.currentLineItem, top=True)
31240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.currentLine = []
31250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if usePos:
31260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.currentLine = [self._position]
31270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
31280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def fill(self, flag=None):
31290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Call fill(True) before drawing a shape to fill, fill(False) when done.
31300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
31310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Optional argument:
31320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        flag -- True/False (or 1/0 respectively)
31330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
31340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Call fill(True) before drawing the shape you want to fill,
31350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        and  fill(False) when done.
31360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        When used without argument: return fillstate (True if filling,
31370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        False else)
31380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
31390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
31400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.fill(True)
31410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(100)
31420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.left(90)
31430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(100)
31440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.left(90)
31450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(100)
31460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.left(90)
31470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(100)
31480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.fill(False)
31490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
31500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        filling = isinstance(self._fillpath, list)
31510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if flag is None:
31520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return filling
31530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        screen = self.screen
31540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        entry1 = entry2 = ()
31550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if filling:
31560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if len(self._fillpath) > 2:
31570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.screen._drawpoly(self._fillitem, self._fillpath,
31580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                      fill=self._fillcolor)
31590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                entry1 = ("dofill", self._fillitem)
31600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if flag:
31610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._fillitem = self.screen._createpoly()
31620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.items.append(self._fillitem)
31630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._fillpath = [self._position]
31640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            entry2 = ("beginfill", self._fillitem) # , self._fillpath)
31650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._newLine()
31660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
31670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._fillitem = self._fillpath = None
31680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.undobuffer:
31690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if entry1 == ():
31700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if entry2 != ():
31710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.undobuffer.push(entry2)
31720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
31730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if entry2 == ():
31740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.undobuffer.push(entry1)
31750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                else:
31760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.undobuffer.push(["seq", entry1, entry2])
31770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._update()
31780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
31790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def begin_fill(self):
31800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Called just before drawing a shape to be filled.
31810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
31820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
31830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
31840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
31850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.begin_fill()
31860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(100)
31870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.left(90)
31880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(100)
31890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.left(90)
31900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(100)
31910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.left(90)
31920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(100)
31930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.end_fill()
31940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
31950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.fill(True)
31960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
31970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def end_fill(self):
31980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Fill the shape drawn after the call begin_fill().
31990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
32000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
32010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
32020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
32030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.begin_fill()
32040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(100)
32050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.left(90)
32060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(100)
32070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.left(90)
32080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(100)
32090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.left(90)
32100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.forward(100)
32110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.end_fill()
32120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
32130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.fill(False)
32140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
32150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def dot(self, size=None, *color):
32160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Draw a dot with diameter size, using color.
32170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
32180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Optional arguments:
32190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        size -- an integer >= 1 (if given)
32200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        color -- a colorstring or a numeric color tuple
32210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
32220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Draw a circular dot with diameter size, using color.
32230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If size is not given, the maximum of pensize+4 and 2*pensize is used.
32240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
32250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
32260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.dot()
32270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50)
32280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
32290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #print "dot-1:", size, color
32300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if not color:
32310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if isinstance(size, (str, tuple)):
32320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                color = self._colorstr(size)
32330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                size = self._pensize + max(self._pensize, 4)
32340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            else:
32350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                color = self._pencolor
32360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if not size:
32370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    size = self._pensize + max(self._pensize, 4)
32380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
32390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if size is None:
32400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                size = self._pensize + max(self._pensize, 4)
32410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            color = self._colorstr(color)
32420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #print "dot-2:", size, color
32430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if hasattr(self.screen, "_dot"):
32440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            item = self.screen._dot(self._position, size, color)
32450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            #print "dot:", size, color, "item:", item
32460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.items.append(item)
32470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self.undobuffer:
32480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.undobuffer.push(("dot", item))
32490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
32500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pen = self.pen()
32510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self.undobuffer:
32520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.undobuffer.push(["seq"])
32530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.undobuffer.cumulate = True
32540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            try:
32550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                if self.resizemode() == 'auto':
32560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                    self.ht()
32570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.pendown()
32580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.pensize(size)
32590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.pencolor(color)
32600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.forward(0)
32610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            finally:
32620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.pen(pen)
32630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if self.undobuffer:
32640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self.undobuffer.cumulate = False
32650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
32660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _write(self, txt, align, font):
32670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Performs the writing for write()
32680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
32690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        item, end = self.screen._write(self._position, txt, align, font,
32700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                                          self._pencolor)
32710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.items.append(item)
32720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.undobuffer:
32730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.undobuffer.push(("wri", item))
32740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return end
32750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
32760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def write(self, arg, move=False, align="left", font=("Arial", 8, "normal")):
32770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Write text at the current turtle position.
32780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
32790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
32800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        arg -- info, which is to be written to the TurtleScreen
32810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        move (optional) -- True/False
32820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        align (optional) -- one of the strings "left", "center" or right"
32830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        font (optional) -- a triple (fontname, fontsize, fonttype)
32840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
32850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Write text - the string representation of arg - at the current
32860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle position according to align ("left", "center" or right")
32870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        and with the given font.
32880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If move is True, the pen is moved to the bottom-right corner
32890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        of the text. By default, move is False.
32900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
32910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
32920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.write('Home = ', True, align="center")
32930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.write((0,0), True)
32940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
32950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.undobuffer:
32960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.undobuffer.push(["seq"])
32970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.undobuffer.cumulate = True
32980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        end = self._write(str(arg), align.lower(), font)
32990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if move:
33000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            x, y = self.pos()
33010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.setpos(end, y)
33020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.undobuffer:
33030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.undobuffer.cumulate = False
33040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def begin_poly(self):
33060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Start recording the vertices of a polygon.
33070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
33090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Start recording the vertices of a polygon. Current turtle position
33110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        is first point of polygon.
33120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
33140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.begin_poly()
33150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
33160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._poly = [self._position]
33170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._creatingPoly = True
33180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def end_poly(self):
33200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Stop recording the vertices of a polygon.
33210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
33230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Stop recording the vertices of a polygon. Current turtle position is
33250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        last point of polygon. This will be connected with the first point.
33260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
33280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.end_poly()
33290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
33300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._creatingPoly = False
33310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def get_poly(self):
33330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return the lastly recorded polygon.
33340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
33360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
33380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> p = turtle.get_poly()
33390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.register_shape("myFavouriteShape", p)
33400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
33410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ## check if there is any poly?  -- 1st solution:
33420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self._poly is not None:
33430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return tuple(self._poly)
33440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def getscreen(self):
33460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return the TurtleScreen object, the turtle is drawing  on.
33470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
33490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Return the TurtleScreen object, the turtle is drawing  on.
33510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        So TurtleScreen-methods can be called for that object.
33520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
33540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> ts = turtle.getscreen()
33550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> ts
33560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        <turtle.TurtleScreen object at 0x0106B770>
33570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> ts.bgcolor("pink")
33580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
33590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.screen
33600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def getturtle(self):
33620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Return the Turtleobject itself.
33630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
33650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Only reasonable use: as a function to return the 'anonymous turtle':
33670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example:
33690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> pet = getturtle()
33700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> pet.fd(50)
33710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> pet
33720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        <turtle.Turtle object at 0x0187D810>
33730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtles()
33740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        [<turtle.Turtle object at 0x0187D810>]
33750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
33760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self
33770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    getpen = getturtle
33790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    ################################################################
33820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    ### screen oriented methods recurring to methods of TurtleScreen
33830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    ################################################################
33840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def window_width(self):
33860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Returns the width of the turtle window.
33870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
33890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
33910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.window_width()
33920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        640
33930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
33940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.screen._window_size()[0]
33950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def window_height(self):
33970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Return the height of the turtle window.
33980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
33990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
34000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
34020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.window_height()
34030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        480
34040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
34050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.screen._window_size()[1]
34060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _delay(self, delay=None):
34080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set delay value which determines speed of turtle animation.
34090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
34100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return self.screen.delay(delay)
34110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    #####   event binding methods   #####
34130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def onclick(self, fun, btn=1, add=None):
34150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Bind fun to mouse-click event on this turtle on canvas.
34160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
34180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fun --  a function with two arguments, to which will be assigned
34190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                the coordinates of the clicked point on the canvas.
34200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        num --  number of the mouse-button defaults to 1 (left mouse button).
34210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        add --  True or False. If True, new binding will be added, otherwise
34220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                it will replace a former binding.
34230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example for the anonymous turtle, i. e. the procedural way:
34250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> def turn(x, y):
34270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     left(360)
34280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...
34290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> onclick(turn)  # Now clicking into the turtle will turn it.
34300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> onclick(None)  # event-binding will be removed
34310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
34320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.screen._onclick(self.turtle._item, fun, btn, add)
34330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._update()
34340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def onrelease(self, fun, btn=1, add=None):
34360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Bind fun to mouse-button-release event on this turtle on canvas.
34370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
34390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fun -- a function with two arguments, to which will be assigned
34400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                the coordinates of the clicked point on the canvas.
34410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        num --  number of the mouse-button defaults to 1 (left mouse button).
34420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a MyTurtle instance named joe):
34440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> class MyTurtle(Turtle):
34450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     def glow(self,x,y):
34460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...             self.fillcolor("red")
34470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     def unglow(self,x,y):
34480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...             self.fillcolor("")
34490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...
34500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> joe = MyTurtle()
34510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> joe.onclick(joe.glow)
34520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> joe.onrelease(joe.unglow)
34530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Clicking on joe turns fillcolor red, unclicking turns it to
34550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        transparent.
34560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
34570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.screen._onrelease(self.turtle._item, fun, btn, add)
34580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._update()
34590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def ondrag(self, fun, btn=1, add=None):
34610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Bind fun to mouse-move event on this turtle on canvas.
34620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
34640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fun -- a function with two arguments, to which will be assigned
34650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi               the coordinates of the clicked point on the canvas.
34660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        num -- number of the mouse-button defaults to 1 (left mouse button).
34670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Every sequence of mouse-move-events on a turtle is preceded by a
34690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        mouse-click event on that turtle.
34700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
34720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> turtle.ondrag(turtle.goto)
34730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Subsequently clicking and dragging a Turtle will move it
34750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        across the screen thereby producing handdrawings (if pen is
34760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        down).
34770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
34780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.screen._ondrag(self.turtle._item, fun, btn, add)
34790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
34810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _undo(self, action, data):
34820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Does the main part of the work for undo()
34830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
34840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.undobuffer is None:
34850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return
34860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if action == "rot":
34870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            angle, degPAU = data
34880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._rotate(-angle*degPAU/self._degreesPerAU)
34890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            dummy = self.undobuffer.pop()
34900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif action == "stamp":
34910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            stitem = data[0]
34920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.clearstamp(stitem)
34930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif action == "go":
34940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._undogoto(data)
34950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif action in ["wri", "dot"]:
34960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            item = data[0]
34970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.screen._delete(item)
34980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.items.remove(item)
34990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif action == "dofill":
35000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            item = data[0]
35010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.screen._drawpoly(item, ((0, 0),(0, 0),(0, 0)),
35020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                  fill="", outline="")
35030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif action == "beginfill":
35040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            item = data[0]
35050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._fillitem = self._fillpath = None
35060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.screen._delete(item)
35070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.items.remove(item)
35080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        elif action == "pen":
35090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            TPen.pen(self, data[0])
35100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.undobuffer.pop()
35110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
35120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def undo(self):
35130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """undo (repeatedly) the last turtle action.
35140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
35150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No argument.
35160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
35170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        undo (repeatedly) the last turtle action.
35180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Number of available undo actions is determined by the size of
35190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        the undobuffer.
35200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
35210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Turtle instance named turtle):
35220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> for i in range(4):
35230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     turtle.fd(50); turtle.lt(80)
35240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...
35250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> for i in range(8):
35260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...     turtle.undo()
35270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        ...
35280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
35290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if self.undobuffer is None:
35300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return
35310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        item = self.undobuffer.pop()
35320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        action = item[0]
35330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        data = item[1:]
35340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if action == "seq":
35350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            while data:
35360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                item = data.pop()
35370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                self._undo(item[0], item[1:])
35380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
35390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._undo(action, data)
35400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
35410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    turtlesize = shapesize
35420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
35430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiRawPen = RawTurtle
35440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
35450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi###  Screen - Singleton  ########################
35460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
35470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef Screen():
35480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Return the singleton screen object.
35490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    If none exists at the moment, create a new one and return it,
35500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    else return the existing one."""
35510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if Turtle._screen is None:
35520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Turtle._screen = _Screen()
35530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return Turtle._screen
35540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
35550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass _Screen(TurtleScreen):
35560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
35570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    _root = None
35580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    _canvas = None
35590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    _title = _CFG["title"]
35600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
35610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self):
35620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # XXX there is no need for this code to be conditional,
35630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # as there will be only a single _Screen instance, anyway
35640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # XXX actually, the turtle demo is injecting root window,
35650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # so perhaps the conditional creation of a root should be
35660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # preserved (perhaps by passing it as an optional parameter)
35670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if _Screen._root is None:
35680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            _Screen._root = self._root = _Root()
35690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._root.title(_Screen._title)
35700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._root.ondestroy(self._destroy)
35710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if _Screen._canvas is None:
35720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            width = _CFG["width"]
35730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            height = _CFG["height"]
35740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            canvwidth = _CFG["canvwidth"]
35750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            canvheight = _CFG["canvheight"]
35760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            leftright = _CFG["leftright"]
35770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            topbottom = _CFG["topbottom"]
35780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self._root.setupcanvas(width, height, canvwidth, canvheight)
35790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            _Screen._canvas = self._root._getcanvas()
35800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            TurtleScreen.__init__(self, _Screen._canvas)
35810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.setup(width, height, leftright, topbottom)
35820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
35830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def setup(self, width=_CFG["width"], height=_CFG["height"],
35840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi              startx=_CFG["leftright"], starty=_CFG["topbottom"]):
35850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """ Set the size and position of the main window.
35860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
35870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Arguments:
35880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        width: as integer a size in pixels, as float a fraction of the screen.
35890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          Default is 50% of screen.
35900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        height: as integer the height in pixels, as float a fraction of the
35910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          screen. Default is 75% of screen.
35920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        startx: if positive, starting position in pixels from the left
35930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          edge of the screen, if negative from the right edge
35940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          Default, startx=None is to center window horizontally.
35950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        starty: if positive, starting position in pixels from the top
35960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          edge of the screen, if negative from the bottom edge
35970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi          Default, starty=None is to center window vertically.
35980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
35990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Examples (for a Screen instance named screen):
36000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.setup (width=200, height=200, startx=0, starty=0)
36010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        sets window to 200x200 pixels, in upper left of screen
36030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.setup(width=.75, height=0.5, startx=None, starty=None)
36050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        sets window to 75% of screen by 50% of screen and centers
36070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
36080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if not hasattr(self._root, "set_geometry"):
36090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return
36100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        sw = self._root.win_width()
36110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        sh = self._root.win_height()
36120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(width, float) and 0 <= width <= 1:
36130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            width = sw*width
36140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if startx is None:
36150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            startx = (sw - width) / 2
36160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isinstance(height, float) and 0 <= height <= 1:
36170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            height = sh*height
36180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if starty is None:
36190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            starty = (sh - height) / 2
36200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._root.set_geometry(width, height, startx, starty)
36210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.update()
36220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def title(self, titlestring):
36240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Set title of turtle-window
36250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Argument:
36270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        titlestring -- a string, to appear in the titlebar of the
36280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                       turtle graphics window.
36290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        This is a method of Screen-class. Not available for TurtleScreen-
36310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        objects.
36320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Screen instance named screen):
36340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.title("Welcome to the turtle-zoo!")
36350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
36360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if _Screen._root is not None:
36370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            _Screen._root.title(titlestring)
36380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        _Screen._title = titlestring
36390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def _destroy(self):
36410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        root = self._root
36420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if root is _Screen._root:
36430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            Turtle._pen = None
36440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            Turtle._screen = None
36450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            _Screen._root = None
36460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            _Screen._canvas = None
36470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        TurtleScreen._RUNNING = True
36480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        root.destroy()
36490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def bye(self):
36510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Shut the turtlegraphics window.
36520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a TurtleScreen instance named screen):
36540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.bye()
36550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
36560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self._destroy()
36570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def exitonclick(self):
36590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Go into mainloop until the mouse is clicked.
36600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        No arguments.
36620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Bind bye() method to mouseclick on TurtleScreen.
36640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If "using_IDLE" - value in configuration dictionary is False
36650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        (default value), enter mainloop.
36660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        If IDLE with -n switch (no subprocess) is used, this value should be
36670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        set to True in turtle.cfg. In this case IDLE's mainloop
36680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        is active also for the client script.
36690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        This is a method of the Screen-class and not available for
36710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        TurtleScreen instances.
36720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Example (for a Screen instance named screen):
36740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        >>> screen.exitonclick()
36750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """
36770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def exitGracefully(x, y):
36780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            """Screen.bye() with two dummy-parameters"""
36790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            self.bye()
36800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        self.onclick(exitGracefully)
36810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if _CFG["using_IDLE"]:
36820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            return
36830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
36840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            mainloop()
36850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        except AttributeError:
36860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            exit(0)
36870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass Turtle(RawTurtle):
36900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """RawTurtle auto-creating (scrolled) canvas.
36910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    When a Turtle object is created or a function derived from some
36930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Turtle method is called a TurtleScreen object is automatically created.
36940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
36950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    _pen = None
36960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    _screen = None
36970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
36980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def __init__(self,
36990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                 shape=_CFG["shape"],
37000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                 undobuffersize=_CFG["undobuffersize"],
37010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                 visible=_CFG["visible"]):
37020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if Turtle._screen is None:
37030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            Turtle._screen = Screen()
37040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        RawTurtle.__init__(self, Turtle._screen,
37050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                           shape=shape,
37060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                           undobuffersize=undobuffersize,
37070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                           visible=visible)
37080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
37090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiPen = Turtle
37100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
37110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _getpen():
37120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Create the 'anonymous' turtle if not already present."""
37130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if Turtle._pen is None:
37140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Turtle._pen = Turtle()
37150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return Turtle._pen
37160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
37170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _getscreen():
37180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Create a TurtleScreen if not already present."""
37190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if Turtle._screen is None:
37200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        Turtle._screen = Screen()
37210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return Turtle._screen
37220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
37230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef write_docstringdict(filename="turtle_docstringdict"):
37240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Create and write docstring-dictionary to file.
37250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
37260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Optional argument:
37270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    filename -- a string, used as filename
37280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                default value is turtle_docstringdict
37290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
37300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Has to be called explicitly, (not used by the turtle-graphics classes)
37310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    The docstring dictionary will be written to the Python script <filname>.py
37320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    It is intended to serve as a template for translation of the docstrings
37330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    into different languages.
37340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
37350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    docsdict = {}
37360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
37370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for methodname in _tg_screen_functions:
37380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        key = "_Screen."+methodname
37390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        docsdict[key] = eval(key).__doc__
37400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for methodname in _tg_turtle_functions:
37410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        key = "Turtle."+methodname
37420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        docsdict[key] = eval(key).__doc__
37430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
37440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    f = open("%s.py" % filename,"w")
37450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    keys = sorted([x for x in docsdict.keys()
37460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                        if x.split('.')[1] not in _alias_list])
37470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    f.write('docsdict = {\n\n')
37480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for key in keys[:-1]:
37490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        f.write('%s :\n' % repr(key))
37500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        f.write('        """%s\n""",\n\n' % docsdict[key])
37510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    key = keys[-1]
37520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    f.write('%s :\n' % repr(key))
37530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    f.write('        """%s\n"""\n\n' % docsdict[key])
37540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    f.write("}\n")
37550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    f.close()
37560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
37570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef read_docstrings(lang):
37580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """Read in docstrings from lang-specific docstring dictionary.
37590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
37600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    Transfer docstrings, translated to lang, from a dictionary-file
37610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    to the methods of classes Screen and Turtle and - in revised form -
37620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    to the corresponding functions.
37630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
37640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    modname = "turtle_docstringdict_%(language)s" % {'language':lang.lower()}
37650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    module = __import__(modname)
37660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    docsdict = module.docsdict
37670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    for key in docsdict:
37680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        #print key
37690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
37700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            eval(key).im_func.__doc__ = docsdict[key]
37710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        except:
37720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            print "Bad docstring-entry: %s" % key
37730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
37740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi_LANGUAGE = _CFG["language"]
37750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
37760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yitry:
37770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if _LANGUAGE != "english":
37780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        read_docstrings(_LANGUAGE)
37790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiexcept ImportError:
37800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    print "Cannot find docsdict for", _LANGUAGE
37810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiexcept:
37820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    print ("Unknown Error when trying to import %s-docstring-dictionary" %
37830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                                                  _LANGUAGE)
37840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
37850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
37860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef getmethparlist(ob):
37870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    "Get strings describing the arguments for the given object"
37880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    argText1 = argText2 = ""
37890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # bit of a hack for methods - turn it into a function
37900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # but we drop the "self" param.
37910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if type(ob)==types.MethodType:
37920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fob = ob.im_func
37930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        argOffset = 1
37940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    else:
37950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fob = ob
37960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        argOffset = 0
37970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    # Try and build one for Python defined functions
37980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if type(fob) in [types.FunctionType, types.LambdaType]:
37990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        try:
38000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            counter = fob.func_code.co_argcount
38010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            items2 = list(fob.func_code.co_varnames[argOffset:counter])
38020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            realArgs = fob.func_code.co_varnames[argOffset:counter]
38030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            defaults = fob.func_defaults or []
38040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            defaults = list(map(lambda name: "=%s" % repr(name), defaults))
38050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            defaults = [""] * (len(realArgs)-len(defaults)) + defaults
38060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            items1 = map(lambda arg, dflt: arg+dflt, realArgs, defaults)
38070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if fob.func_code.co_flags & 0x4:
38080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                items1.append("*"+fob.func_code.co_varnames[counter])
38090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                items2.append("*"+fob.func_code.co_varnames[counter])
38100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                counter += 1
38110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if fob.func_code.co_flags & 0x8:
38120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                items1.append("**"+fob.func_code.co_varnames[counter])
38130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                items2.append("**"+fob.func_code.co_varnames[counter])
38140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            argText1 = ", ".join(items1)
38150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            argText1 = "(%s)" % argText1
38160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            argText2 = ", ".join(items2)
38170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            argText2 = "(%s)" % argText2
38180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        except:
38190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pass
38200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return argText1, argText2
38210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
38220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _turtle_docrevise(docstr):
38230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """To reduce docstrings from RawTurtle class for functions
38240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
38250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    import re
38260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if docstr is None:
38270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return None
38280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    turtlename = _CFG["exampleturtle"]
38290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    newdocstr = docstr.replace("%s." % turtlename,"")
38300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    parexp = re.compile(r' \(.+ %s\):' % turtlename)
38310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    newdocstr = parexp.sub(":", newdocstr)
38320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return newdocstr
38330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
38340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _screen_docrevise(docstr):
38350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """To reduce docstrings from TurtleScreen class for functions
38360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    """
38370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    import re
38380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if docstr is None:
38390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        return None
38400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    screenname = _CFG["examplescreen"]
38410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    newdocstr = docstr.replace("%s." % screenname,"")
38420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    parexp = re.compile(r' \(.+ %s\):' % screenname)
38430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    newdocstr = parexp.sub(":", newdocstr)
38440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    return newdocstr
38450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
38460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## The following mechanism makes all methods of RawTurtle and Turtle available
38470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## as functions. So we can enhance, change, add, delete methods to these
38480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## classes and do not need to change anything here.
38490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
38500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
38510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifor methodname in _tg_screen_functions:
38520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    pl1, pl2 = getmethparlist(eval('_Screen.' + methodname))
38530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if pl1 == "":
38540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        print ">>>>>>", pl1, pl2
38550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        continue
38560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    defstr = ("def %(key)s%(pl1)s: return _getscreen().%(key)s%(pl2)s" %
38570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                   {'key':methodname, 'pl1':pl1, 'pl2':pl2})
38580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    exec defstr
38590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    eval(methodname).__doc__ = _screen_docrevise(eval('_Screen.'+methodname).__doc__)
38600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
38610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifor methodname in _tg_turtle_functions:
38620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    pl1, pl2 = getmethparlist(eval('Turtle.' + methodname))
38630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    if pl1 == "":
38640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        print ">>>>>>", pl1, pl2
38650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        continue
38660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    defstr = ("def %(key)s%(pl1)s: return _getpen().%(key)s%(pl2)s" %
38670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                                   {'key':methodname, 'pl1':pl1, 'pl2':pl2})
38680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    exec defstr
38690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    eval(methodname).__doc__ = _turtle_docrevise(eval('Turtle.'+methodname).__doc__)
38700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
38710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
38720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidone = mainloop = TK.mainloop
38730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidel pl1, pl2, defstr
38740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
38750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiif __name__ == "__main__":
38760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def switchpen():
38770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        if isdown():
38780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pu()
38790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        else:
38800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            pd()
38810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
38820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def demo1():
38830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Demo of old turtle.py - module"""
38840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        reset()
38850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tracer(True)
38860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        up()
38870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        backward(100)
38880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        down()
38890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # draw 3 squares; the last filled
38900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        width(3)
38910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for i in range(3):
38920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if i == 2:
38930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                fill(1)
38940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for _ in range(4):
38950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                forward(20)
38960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                left(90)
38970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if i == 2:
38980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                color("maroon")
38990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                fill(0)
39000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            up()
39010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            forward(30)
39020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            down()
39030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        width(1)
39040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        color("black")
39050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # move out of the way
39060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tracer(False)
39070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        up()
39080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        right(90)
39090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        forward(100)
39100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        right(90)
39110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        forward(100)
39120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        right(180)
39130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        down()
39140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # some text
39150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        write("startstart", 1)
39160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        write("start", 1)
39170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        color("red")
39180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # staircase
39190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for i in range(5):
39200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            forward(20)
39210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            left(90)
39220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            forward(20)
39230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            right(90)
39240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # filled staircase
39250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tracer(True)
39260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fill(1)
39270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for i in range(5):
39280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            forward(20)
39290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            left(90)
39300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            forward(20)
39310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            right(90)
39320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fill(0)
39330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        # more text
39340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
39350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    def demo2():
39360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        """Demo of some new features."""
39370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        speed(1)
39380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        st()
39390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pensize(3)
39400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        setheading(towards(0, 0))
39410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        radius = distance(0, 0)/2.0
39420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        rt(90)
39430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for _ in range(18):
39440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            switchpen()
39450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            circle(radius, 10)
39460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        write("wait a moment...")
39470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        while undobufferentries():
39480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            undo()
39490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        reset()
39500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        lt(90)
39510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        colormode(255)
39520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        laenge = 10
39530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pencolor("green")
39540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pensize(3)
39550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        lt(180)
39560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for i in range(-2, 16):
39570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if i > 0:
39580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                begin_fill()
39590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                fillcolor(255-15*i, 0, 15*i)
39600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            for _ in range(3):
39610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                fd(laenge)
39620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                lt(120)
39630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            laenge += 10
39640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            lt(15)
39650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            speed((speed()+1)%12)
39660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        end_fill()
39670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
39680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        lt(120)
39690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pu()
39700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fd(70)
39710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        rt(30)
39720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pd()
39730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        color("red","yellow")
39740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        speed(0)
39750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fill(1)
39760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        for _ in range(4):
39770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            circle(50, 90)
39780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            rt(90)
39790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            fd(30)
39800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            rt(90)
39810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fill(0)
39820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        lt(90)
39830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pu()
39840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        fd(30)
39850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        pd()
39860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        shape("turtle")
39870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
39880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tri = getturtle()
39890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tri.resizemode("auto")
39900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle = Turtle()
39910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle.resizemode("auto")
39920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle.shape("turtle")
39930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle.reset()
39940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle.left(90)
39950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle.speed(0)
39960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle.up()
39970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle.goto(280, 40)
39980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle.lt(30)
39990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle.down()
40000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle.speed(6)
40010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle.color("blue","orange")
40020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        turtle.pensize(2)
40030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tri.speed(6)
40040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        setheading(towards(turtle))
40050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        count = 1
40060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        while tri.distance(turtle) > 4:
40070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            turtle.fd(3.5)
40080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            turtle.lt(0.6)
40090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            tri.setheading(tri.towards(turtle))
40100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            tri.fd(4)
40110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            if count % 20 == 0:
40120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                turtle.stamp()
40130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                tri.stamp()
40140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi                switchpen()
40150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            count += 1
40160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tri.write("CAUGHT! ", font=("Arial", 16, "bold"), align="right")
40170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tri.pencolor("black")
40180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tri.pencolor("red")
40190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
40200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        def baba(xdummy, ydummy):
40210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            clearscreen()
40220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            bye()
40230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
40240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        time.sleep(2)
40250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
40260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        while undobufferentries():
40270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            tri.undo()
40280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi            turtle.undo()
40290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tri.fd(50)
40300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tri.write("  Click me!", font = ("Courier", 12, "bold") )
40310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi        tri.onclick(baba, 1)
40320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi
40330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    demo1()
40340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    demo2()
40350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi    exitonclick()
4036