turtle.py revision 7dde792e62c8adeaf5d633dc89e18d16067add8e
197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis#
297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis# turtle.py: a Tkinter based turtle graphics module for Python
3eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl# Version 1.1b - 4. 5. 2009
497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis#
546a9900e099a82cda7328b0de16d6fffe52ee62aBenjamin Peterson# Copyright (C) 2006 - 2010  Gregor Lingl
697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis# email: glingl@aon.at
797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis#
897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis# This software is provided 'as-is', without any express or implied
997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis# warranty.  In no event will the authors be held liable for any damages
1097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis# arising from the use of this software.
1197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis#
1297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis# Permission is granted to anyone to use this software for any purpose,
1397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis# including commercial applications, and to alter it and redistribute it
1497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis# freely, subject to the following restrictions:
1597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis#
1697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis# 1. The origin of this software must not be misrepresented; you must not
1797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis#    claim that you wrote the original software. If you use this software
1897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis#    in a product, an acknowledgment in the product documentation would be
1997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis#    appreciated but is not required.
2097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis# 2. Altered source versions must be plainly marked as such, and must not be
2197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis#    misrepresented as being the original software.
2297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis# 3. This notice may not be removed or altered from any source distribution.
2397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
24b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
25477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters"""
26477c8d5e70240744d24631b18341ad892c8a8e1cThomas WoutersTurtle graphics is a popular way for introducing programming to
27477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouterskids. It was part of the original Logo programming language developed
2897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisby Wally Feurzig and Seymour Papert in 1966.
29477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
30477c8d5e70240744d24631b18341ad892c8a8e1cThomas WoutersImagine a robotic turtle starting at (0, 0) in the x-y plane. Give it
31477c8d5e70240744d24631b18341ad892c8a8e1cThomas Woutersthe command turtle.forward(15), and it moves (on-screen!) 15 pixels in
32477c8d5e70240744d24631b18341ad892c8a8e1cThomas Woutersthe direction it is facing, drawing a line as it moves. Give it the
33477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouterscommand turtle.left(25), and it rotates in-place 25 degrees clockwise.
34477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
35477c8d5e70240744d24631b18341ad892c8a8e1cThomas WoutersBy combining together these and similar commands, intricate shapes and
36477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouterspictures can easily be drawn.
3797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
3897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis----- turtle.py
3997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
4097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. LöwisThis module is an extended reimplementation of turtle.py from the
41f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark DickinsonPython standard distribution up to Python 2.5. (See: http://www.python.org)
4297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
4397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. LöwisIt tries to keep the merits of turtle.py and to be (nearly) 100%
4497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwiscompatible with it. This means in the first place to enable the
4597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwislearning programmer to use all the commands, classes and methods
4697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisinteractively when using the module from within IDLE run with
4797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisthe -n switch.
4897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
4997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. LöwisRoughly it has the following features added:
5097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
5197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis- Better animation of the turtle movements, especially of turning the
5297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  turtle. So the turtles can more easily be used as a visual feedback
5397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  instrument by the (beginning) programmer.
5497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
5597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis- Different turtle shapes, gif-images as turtle shapes, user defined
5697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  and user controllable turtle shapes, among them compound
57f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson  (multicolored) shapes. Turtle shapes can be stretched and tilted, which
580fc61ccbba42dcebdf97a981e39d8522b24d60bcMark Dickinson  makes turtles very versatile geometrical objects.
5997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
6097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis- Fine control over turtle movement and screen updates via delay(),
6197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  and enhanced tracer() and speed() methods.
6297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
6397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis- Aliases for the most commonly used commands, like fd for forward etc.,
6497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  following the early Logo traditions. This reduces the boring work of
6597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  typing long sequences of commands, which often occur in a natural way
6697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  when kids try to program fancy pictures on their first encounter with
67f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson  turtle graphics.
6897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
6997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis- Turtles now have an undo()-method with configurable undo-buffer.
7097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
7197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis- Some simple commands/methods for creating event driven programs
7297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  (mouse-, key-, timer-events). Especially useful for programming games.
7397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
7497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis- A scrollable Canvas class. The default scrollable Canvas can be
7597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  extended interactively as needed while playing around with the turtle(s).
7697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
7797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis- A TurtleScreen class with methods controlling background color or
7897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  background image, window and canvas size and other properties of the
7997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  TurtleScreen.
8097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
8197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis- There is a method, setworldcoordinates(), to install a user defined
8297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  coordinate-system for the TurtleScreen.
8397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
8497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis- The implementation uses a 2-vector class named Vec2D, derived from tuple.
8597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  This class is public, so it can be imported by the application programmer,
8697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  which makes certain types of computations very natural and compact.
8797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
8897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis- Appearance of the TurtleScreen and the Turtles at startup/import can be
8997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  configured by means of a turtle.cfg configuration file.
9097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  The default configuration mimics the appearance of the old turtle module.
9197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
9297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis- If configured appropriately the module reads in docstrings from a docstring
9397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  dictionary in some different language, supplied separately  and replaces
94f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson  the English ones by those read in. There is a utility function
95f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson  write_docstringdict() to write a dictionary with the original (English)
9697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis  docstrings to disc, so it can serve as a template for translations.
9797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
9897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. LöwisBehind the scenes there are some features included with possible
99f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinsonextensions in in mind. These will be commented and documented elsewhere.
10097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
101477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters"""
102477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
103eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl_ver = "turtle 1.1b- - for Python 3.1   -  4. 5. 2009"
10497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
10597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis# print(_ver)
10697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
10797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisimport tkinter as TK
10897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisimport types
10997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisimport math
11097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisimport time
11197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisimport os
11297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
11397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisfrom os.path import isfile, split, join
11497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisfrom copy import deepcopy
115eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandlfrom tkinter import simpledialog
11697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
11797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis_tg_classes = ['ScrolledCanvas', 'TurtleScreen', 'Screen',
11897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis               'RawTurtle', 'Turtle', 'RawPen', 'Pen', 'Shape', 'Vec2D']
11997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis_tg_screen_functions = ['addshape', 'bgcolor', 'bgpic', 'bye',
12097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'clearscreen', 'colormode', 'delay', 'exitonclick', 'getcanvas',
121eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'getshapes', 'listen', 'mainloop', 'mode', 'numinput',
122eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'onkey', 'onkeypress', 'onkeyrelease', 'onscreenclick', 'ontimer',
12397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'register_shape', 'resetscreen', 'screensize', 'setup',
124eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'setworldcoordinates', 'textinput', 'title', 'tracer', 'turtles', 'update',
12597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'window_height', 'window_width']
12697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis_tg_turtle_functions = ['back', 'backward', 'begin_fill', 'begin_poly', 'bk',
12797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'circle', 'clear', 'clearstamp', 'clearstamps', 'clone', 'color',
12897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'degrees', 'distance', 'dot', 'down', 'end_fill', 'end_poly', 'fd',
12946afef330f88ddcf4106094e86f54f90dbdec390Georg Brandl        'fillcolor', 'filling', 'forward', 'get_poly', 'getpen', 'getscreen', 'get_shapepoly',
13097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'getturtle', 'goto', 'heading', 'hideturtle', 'home', 'ht', 'isdown',
13197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'isvisible', 'left', 'lt', 'onclick', 'ondrag', 'onrelease', 'pd',
13297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'pen', 'pencolor', 'pendown', 'pensize', 'penup', 'pos', 'position',
13397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'pu', 'radians', 'right', 'reset', 'resizemode', 'rt',
13497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'seth', 'setheading', 'setpos', 'setposition', 'settiltangle',
135eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'setundobuffer', 'setx', 'sety', 'shape', 'shapesize', 'shapetransform', 'shearfactor', 'showturtle',
136eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'speed', 'st', 'stamp', 'tilt', 'tiltangle', 'towards',
13797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'turtlesize', 'undo', 'undobufferentries', 'up', 'width',
13897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'write', 'xcor', 'ycor']
139eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl_tg_utilities = ['write_docstringdict', 'done']
14097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
14197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis__all__ = (_tg_classes + _tg_screen_functions + _tg_turtle_functions +
14297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           _tg_utilities) # + _math_functions)
14397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
14497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis_alias_list = ['addshape', 'backward', 'bk', 'fd', 'ht', 'lt', 'pd', 'pos',
14597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis               'pu', 'rt', 'seth', 'setpos', 'setposition', 'st',
14697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis               'turtlesize', 'up', 'width']
14797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
14897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis_CFG = {"width" : 0.5,               # Screen
14997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "height" : 0.75,
15097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "canvwidth" : 400,
15197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "canvheight": 300,
15297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "leftright": None,
15397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "topbottom": None,
15497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "mode": "standard",          # TurtleScreen
15597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "colormode": 1.0,
15697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "delay": 10,
15797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "undobuffersize": 1000,      # RawTurtle
15897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "shape": "classic",
15997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "pencolor" : "black",
16097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "fillcolor" : "black",
16197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "resizemode" : "noresize",
16297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "visible" : True,
16397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "language": "english",        # docstrings
16497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "exampleturtle": "turtle",
16597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "examplescreen": "screen",
16697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "title": "Python Turtle Graphics",
16797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "using_IDLE": False
16897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       }
16997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
17097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef config_dict(filename):
17197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Convert content of config-file into dictionary."""
1727dde792e62c8adeaf5d633dc89e18d16067add8eFlorent Xicluna    with open(filename, "r") as f:
1737dde792e62c8adeaf5d633dc89e18d16067add8eFlorent Xicluna        cfglines = f.readlines()
17497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    cfgdict = {}
17597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for line in cfglines:
17697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        line = line.strip()
17797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not line or line.startswith("#"):
17897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            continue
17997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        try:
18097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            key, value = line.split("=")
18197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        except:
18297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            print("Bad line in config-file %s:\n%s" % (filename,line))
18397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            continue
18497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        key = key.strip()
18597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        value = value.strip()
18697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if value in ["True", "False", "None", "''", '""']:
18797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            value = eval(value)
18897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
18997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            try:
19097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if "." in value:
19197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    value = float(value)
19297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                else:
19397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    value = int(value)
19497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            except:
19597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                pass # value need not be converted
19697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cfgdict[key] = value
19797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    return cfgdict
19897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
19997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef readconfig(cfgdict):
20097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Read config-files, change configuration-dict accordingly.
20197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
20297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    If there is a turtle.cfg file in the current working directory,
20397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    read it from there. If this contains an importconfig-value,
20497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    say 'myway', construct filename turtle_mayway.cfg else use
20597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    turtle.cfg and read it from the import-directory, where
20697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    turtle.py is located.
20797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Update configuration dictionary first according to config-file,
20897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    in the import directory, then according to config-file in the
20997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    current working directory.
21097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    If no config-file is found, the default configuration is used.
21197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
21297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    default_cfg = "turtle.cfg"
21397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    cfgdict1 = {}
21497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    cfgdict2 = {}
21597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if isfile(default_cfg):
21697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cfgdict1 = config_dict(default_cfg)
21797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if "importconfig" in cfgdict1:
21897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        default_cfg = "turtle_%s.cfg" % cfgdict1["importconfig"]
21997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    try:
22097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        head, tail = split(__file__)
22197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cfg_file2 = join(head, default_cfg)
22297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    except:
22397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cfg_file2 = ""
22497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if isfile(cfg_file2):
22597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cfgdict2 = config_dict(cfg_file2)
22697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _CFG.update(cfgdict2)
22797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _CFG.update(cfgdict1)
22897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
22997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwistry:
23097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    readconfig(_CFG)
23197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisexcept:
23297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    print ("No configfile read, reason unknown")
23397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
23497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
23597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass Vec2D(tuple):
23697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """A 2 dimensional vector class, used as a helper class
23797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for implementing turtle graphics.
23897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    May be useful for turtle graphics programs also.
23997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Derived from tuple, so a vector is a tuple!
24097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
24197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Provides (for a, b vectors, k number):
24297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       a+b vector addition
24397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       a-b vector subtraction
24497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       a*b inner product
24597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       k*a and a*k multiplication with scalar
24697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       |a| absolute value of a
24797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       a.rotate(angle) rotation
24897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
24997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __new__(cls, x, y):
25097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return tuple.__new__(cls, (x, y))
25197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __add__(self, other):
25297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return Vec2D(self[0]+other[0], self[1]+other[1])
25397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __mul__(self, other):
25497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(other, Vec2D):
25597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self[0]*other[0]+self[1]*other[1]
25697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return Vec2D(self[0]*other, self[1]*other)
25797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __rmul__(self, other):
25897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(other, int) or isinstance(other, float):
25997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return Vec2D(self[0]*other, self[1]*other)
26097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __sub__(self, other):
26197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return Vec2D(self[0]-other[0], self[1]-other[1])
26297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __neg__(self):
26397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return Vec2D(-self[0], -self[1])
26497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __abs__(self):
26597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return (self[0]**2 + self[1]**2)**0.5
26697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def rotate(self, angle):
26797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """rotate self counterclockwise by angle
26897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
26997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        perp = Vec2D(-self[1], self[0])
27097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle = angle * math.pi / 180.0
27197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        c, s = math.cos(angle), math.sin(angle)
27297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return Vec2D(self[0]*c+perp[0]*s, self[1]*c+perp[1]*s)
27397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __getnewargs__(self):
27497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return (self[0], self[1])
27597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __repr__(self):
27697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return "(%.2f,%.2f)" % self
27797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
27897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
27997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis##############################################################################
28097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis### From here up to line    : Tkinter - Interface for turtle.py            ###
281f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson### May be replaced by an interface to some different graphics toolkit     ###
28297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis##############################################################################
28397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
28497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis## helper functions for Scrolled Canvas, to forward Canvas-methods
28597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis## to ScrolledCanvas class
28697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
28797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef __methodDict(cls, _dict):
28897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """helper function for Scrolled Canvas"""
28997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    baseList = list(cls.__bases__)
29097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    baseList.reverse()
29197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for _super in baseList:
29297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        __methodDict(_super, _dict)
29397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for key, value in cls.__dict__.items():
29497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if type(value) == types.FunctionType:
29597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            _dict[key] = value
29697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
29797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef __methods(cls):
29897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """helper function for Scrolled Canvas"""
29997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _dict = {}
30097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    __methodDict(cls, _dict)
30197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    return _dict.keys()
30297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
30397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis__stringBody = (
30497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    'def %(method)s(self, *args, **kw): return ' +
30597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    'self.%(attribute)s.%(method)s(*args, **kw)')
30697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
30797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef __forwardmethods(fromClass, toClass, toPart, exclude = ()):
30897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    ### MANY CHANGES ###
30997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _dict_1 = {}
31097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    __methodDict(toClass, _dict_1)
31197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _dict = {}
31297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    mfc = __methods(fromClass)
31397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for ex in _dict_1.keys():
31497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if ex[:1] == '_' or ex[-1:] == '_' or ex in exclude or ex in mfc:
31597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pass
31697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
31797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            _dict[ex] = _dict_1[ex]
31897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
31997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for method, func in _dict.items():
32097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        d = {'method': method, 'func': func}
32197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(toPart, str):
32297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            execString = \
32397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                __stringBody % {'method' : method, 'attribute' : toPart}
32497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        exec(execString, d)
32597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        setattr(fromClass, method, d[method])   ### NEWU!
32697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
32797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
32897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass ScrolledCanvas(TK.Frame):
32997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Modeled after the scrolled canvas class from Grayons's Tkinter book.
33097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
33197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Used as the default canvas, which pops up automatically when
33297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    using turtle graphics functions or the Turtle class.
33397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
33497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, master, width=500, height=350,
33597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                          canvwidth=600, canvheight=500):
33697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TK.Frame.__init__(self, master, width=width, height=height)
33722d297be51567eb193e792a0da52b93e9a45b9a4Martin v. Löwis        self._rootwindow = self.winfo_toplevel()
33897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.width, self.height = width, height
33997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.canvwidth, self.canvheight = canvwidth, canvheight
34097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.bg = "white"
34197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas = TK.Canvas(master, width=width, height=height,
34297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                 bg=self.bg, relief=TK.SUNKEN, borderwidth=2)
34397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.hscroll = TK.Scrollbar(master, command=self._canvas.xview,
34497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                    orient=TK.HORIZONTAL)
34597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.vscroll = TK.Scrollbar(master, command=self._canvas.yview)
34697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.configure(xscrollcommand=self.hscroll.set,
34797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                               yscrollcommand=self.vscroll.set)
34897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.rowconfigure(0, weight=1, minsize=0)
34997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.columnconfigure(0, weight=1, minsize=0)
35097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.grid(padx=1, in_ = self, pady=1, row=0,
35197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                column=0, rowspan=1, columnspan=1, sticky='news')
35297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
35397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                column=1, rowspan=1, columnspan=1, sticky='news')
35497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
35597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                column=0, rowspan=1, columnspan=1, sticky='news')
35697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.reset()
35722d297be51567eb193e792a0da52b93e9a45b9a4Martin v. Löwis        self._rootwindow.bind('<Configure>', self.onResize)
35897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
35997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def reset(self, canvwidth=None, canvheight=None, bg = None):
360f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        """Adjust canvas and scrollbars according to given canvas size."""
36197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if canvwidth:
36297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.canvwidth = canvwidth
36397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if canvheight:
36497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.canvheight = canvheight
36597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if bg:
36697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.bg = bg
36797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.config(bg=bg,
36897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                        scrollregion=(-self.canvwidth//2, -self.canvheight//2,
36997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                       self.canvwidth//2, self.canvheight//2))
37097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.xview_moveto(0.5*(self.canvwidth - self.width + 30) /
37197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                               self.canvwidth)
37297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.yview_moveto(0.5*(self.canvheight- self.height + 30) /
37397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                              self.canvheight)
37497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.adjustScrolls()
37597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
37697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
37797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def adjustScrolls(self):
37897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Adjust scrollbars according to window- and canvas-size.
37997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
38097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cwidth = self._canvas.winfo_width()
38197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cheight = self._canvas.winfo_height()
38297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.xview_moveto(0.5*(self.canvwidth-cwidth)/self.canvwidth)
38397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.yview_moveto(0.5*(self.canvheight-cheight)/self.canvheight)
38497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if cwidth < self.canvwidth or cheight < self.canvheight:
38597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
38697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              column=0, rowspan=1, columnspan=1, sticky='news')
38797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
38897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              column=1, rowspan=1, columnspan=1, sticky='news')
38997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
39097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.hscroll.grid_forget()
39197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.vscroll.grid_forget()
39297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
39397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def onResize(self, event):
39497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """self-explanatory"""
39597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.adjustScrolls()
39697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
39797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def bbox(self, *args):
39897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ 'forward' method, which canvas itself has inherited...
39997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
40097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._canvas.bbox(*args)
40197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
40297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def cget(self, *args, **kwargs):
40397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ 'forward' method, which canvas itself has inherited...
40497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
40597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._canvas.cget(*args, **kwargs)
40697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
40797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def config(self, *args, **kwargs):
40897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ 'forward' method, which canvas itself has inherited...
40997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
41097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.config(*args, **kwargs)
41197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
41297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def bind(self, *args, **kwargs):
41397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ 'forward' method, which canvas itself has inherited...
41497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
41597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.bind(*args, **kwargs)
41697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
41797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def unbind(self, *args, **kwargs):
41897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ 'forward' method, which canvas itself has inherited...
41997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
42097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.unbind(*args, **kwargs)
42197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
42297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def focus_force(self):
42397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ 'forward' method, which canvas itself has inherited...
42497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
42597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.focus_force()
42697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
42797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis__forwardmethods(ScrolledCanvas, TK.Canvas, '_canvas')
42897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
42997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
43097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass _Root(TK.Tk):
43197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Root class for Screen based on Tkinter."""
43297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self):
43397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TK.Tk.__init__(self)
43497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
43597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def setupcanvas(self, width, height, cwidth, cheight):
43697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas = ScrolledCanvas(self, width, height, cwidth, cheight)
43797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.pack(expand=1, fill="both")
43897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
43997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _getcanvas(self):
44097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._canvas
441fd2ede2aa84e77dac30e297a04fc49dd3bb61c68Guido van Rossum
44297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def set_geometry(self, width, height, startx, starty):
44397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.geometry("%dx%d%+d%+d"%(width, height, startx, starty))
444477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
44597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def ondestroy(self, destroy):
44697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.wm_protocol("WM_DELETE_WINDOW", destroy)
44797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
44897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def win_width(self):
44997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.winfo_screenwidth()
45097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
45197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def win_height(self):
45297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.winfo_screenheight()
45397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
45497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. LöwisCanvas = TK.Canvas
45597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
45697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
45797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass TurtleScreenBase(object):
45897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Provide the basic graphics functionality.
45997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       Interface between Tkinter and turtle.py.
46097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
46197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       To port turtle.py to some different graphics toolkit
46297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       a corresponding TurtleScreenBase class has to be implemented.
46397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
46497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
46597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    @staticmethod
46697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _blankimage():
46797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """return a blank image object
46897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
46997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        img = TK.PhotoImage(width=1, height=1)
47097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        img.blank()
47197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return img
47297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
47397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    @staticmethod
47497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _image(filename):
47597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """return an image object containing the
47697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        imagedata from a gif-file named filename.
47797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
47897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return TK.PhotoImage(file=filename)
47997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
48097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, cv):
48197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv = cv
48297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(cv, ScrolledCanvas):
48397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            w = self.cv.canvwidth
48497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            h = self.cv.canvheight
48597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:  # expected: ordinary TK.Canvas
48697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            w = int(self.cv.cget("width"))
48797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            h = int(self.cv.cget("height"))
48897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.config(scrollregion = (-w//2, -h//2, w//2, h//2 ))
48997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.canvwidth = w
49097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.canvheight = h
49197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.xscale = self.yscale = 1.0
49297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
49397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _createpoly(self):
49497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Create an invisible polygon item on canvas self.cv)
49597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
49697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.cv.create_polygon((0, 0, 0, 0, 0, 0), fill="", outline="")
49797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
49897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _drawpoly(self, polyitem, coordlist, fill=None,
49997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                  outline=None, width=None, top=False):
50097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Configure polygonitem polyitem according to provided
50197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        arguments:
50297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        coordlist is sequence of coordinates
50397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fill is filling color
50497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        outline is outline color
50597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        top is a boolean value, which specifies if polyitem
50697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        will be put on top of the canvas' displaylist so it
50797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        will not be covered by other items.
50897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
50997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cl = []
51097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for x, y in coordlist:
51197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            cl.append(x * self.xscale)
51297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            cl.append(-y * self.yscale)
51397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.coords(polyitem, *cl)
51497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if fill is not None:
51597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.itemconfigure(polyitem, fill=fill)
51697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if outline is not None:
51797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.itemconfigure(polyitem, outline=outline)
51897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if width is not None:
51997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.itemconfigure(polyitem, width=width)
52097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if top:
52197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_raise(polyitem)
52297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
52397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _createline(self):
52497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Create an invisible line item on canvas self.cv)
52597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
52697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.cv.create_line(0, 0, 0, 0, fill="", width=2,
52797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                   capstyle = TK.ROUND)
52897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
52997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _drawline(self, lineitem, coordlist=None,
53097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                  fill=None, width=None, top=False):
53197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Configure lineitem according to provided arguments:
53297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        coordlist is sequence of coordinates
53397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fill is drawing color
53497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        width is width of drawn line.
53597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        top is a boolean value, which specifies if polyitem
53697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        will be put on top of the canvas' displaylist so it
53797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        will not be covered by other items.
53897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
53997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if coordlist is not None:
54097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            cl = []
54197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for x, y in coordlist:
54297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                cl.append(x * self.xscale)
54397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                cl.append(-y * self.yscale)
54497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.coords(lineitem, *cl)
54597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if fill is not None:
54697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.itemconfigure(lineitem, fill=fill)
54797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if width is not None:
54897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.itemconfigure(lineitem, width=width)
54997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if top:
55097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_raise(lineitem)
55197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
55297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _delete(self, item):
55397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Delete graphics item from canvas.
55497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If item is"all" delete all graphics items.
55597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
55697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.delete(item)
55797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
55897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _update(self):
55997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Redraw graphics items on canvas
56097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
56197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.update()
56297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
56397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _delay(self, delay):
56497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Delay subsequent canvas actions for delay ms."""
56597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.after(delay)
56697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
56797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _iscolorstring(self, color):
56897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Check if the string color is a legal Tkinter color string.
56997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
57097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        try:
57197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            rgb = self.cv.winfo_rgb(color)
57297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            ok = True
57397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        except TK.TclError:
57497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            ok = False
57597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return ok
57697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
57797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _bgcolor(self, color=None):
57897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set canvas' backgroundcolor if color is not None,
57997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else return backgroundcolor."""
58097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if color is not None:
58197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.config(bg = color)
58297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._update()
58397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
58497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self.cv.cget("bg")
58597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
58697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _write(self, pos, txt, align, font, pencolor):
58797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Write txt at pos in canvas with specified font
58897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        and color.
58997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Return text item and x-coord of right bottom corner
59097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of text's bounding box."""
59197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x, y = pos
59297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x = x * self.xscale
59397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        y = y * self.yscale
59497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        anchor = {"left":"sw", "center":"s", "right":"se" }
59597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        item = self.cv.create_text(x-1, -y, text = txt, anchor = anchor[align],
59697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                        fill = pencolor, font = font)
59797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x0, y0, x1, y1 = self.cv.bbox(item)
59897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.update()
59997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return item, x1-1
60097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
60197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis##    def _dot(self, pos, size, color):
60297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis##        """may be implemented for some other graphics toolkit"""
60397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
60497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _onclick(self, item, fun, num=1, add=None):
60597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-click event on turtle.
60697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun must be a function with two arguments, the coordinates
60797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of the clicked point on the canvas.
60897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num, the number of the mouse-button defaults to 1
60997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
61097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if fun is None:
61197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_unbind(item, "<Button-%s>" % num)
61297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
61397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            def eventfun(event):
61497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                x, y = (self.cv.canvasx(event.x)/self.xscale,
61597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                        -self.cv.canvasy(event.y)/self.yscale)
61697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fun(x, y)
61797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_bind(item, "<Button-%s>" % num, eventfun, add)
61897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
61997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _onrelease(self, item, fun, num=1, add=None):
62097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-button-release event on turtle.
62197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun must be a function with two arguments, the coordinates
62297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of the point on the canvas where mouse button is released.
62397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num, the number of the mouse-button defaults to 1
62497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
62597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If a turtle is clicked, first _onclick-event will be performed,
62697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        then _onscreensclick-event.
62797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
62897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if fun is None:
62997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_unbind(item, "<Button%s-ButtonRelease>" % num)
63097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
63197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            def eventfun(event):
63297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                x, y = (self.cv.canvasx(event.x)/self.xscale,
63397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                        -self.cv.canvasy(event.y)/self.yscale)
63497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fun(x, y)
63597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_bind(item, "<Button%s-ButtonRelease>" % num,
63697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                             eventfun, add)
63797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
63897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _ondrag(self, item, fun, num=1, add=None):
63997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-move-event (with pressed mouse button) on turtle.
64097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun must be a function with two arguments, the coordinates of the
64197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        actual mouse position on the canvas.
64297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num, the number of the mouse-button defaults to 1
64397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
64497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Every sequence of mouse-move-events on a turtle is preceded by a
64597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        mouse-click event on that turtle.
64697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
64797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if fun is None:
64897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_unbind(item, "<Button%s-Motion>" % num)
64997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
65097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            def eventfun(event):
65197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                try:
65297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    x, y = (self.cv.canvasx(event.x)/self.xscale,
65397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                           -self.cv.canvasy(event.y)/self.yscale)
65497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    fun(x, y)
65597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                except:
65697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    pass
65797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_bind(item, "<Button%s-Motion>" % num, eventfun, add)
65897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
65997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _onscreenclick(self, fun, num=1, add=None):
66097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-click event on canvas.
66197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun must be a function with two arguments, the coordinates
66297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of the clicked point on the canvas.
66397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num, the number of the mouse-button defaults to 1
66497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
66597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If a turtle is clicked, first _onclick-event will be performed,
66697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        then _onscreensclick-event.
66797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
66897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if fun is None:
66997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.unbind("<Button-%s>" % num)
67097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
67197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            def eventfun(event):
67297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                x, y = (self.cv.canvasx(event.x)/self.xscale,
67397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                        -self.cv.canvasy(event.y)/self.yscale)
67497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fun(x, y)
67597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.bind("<Button-%s>" % num, eventfun, add)
67697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
677eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def _onkeyrelease(self, fun, key):
67897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to key-release event of key.
67997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Canvas must have focus. See method listen
68097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
68197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if fun is None:
68297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.unbind("<KeyRelease-%s>" % key, None)
68397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
68497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            def eventfun(event):
68597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fun()
68697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.bind("<KeyRelease-%s>" % key, eventfun)
68797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
688eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def _onkeypress(self, fun, key=None):
689eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """If key is given, bind fun to key-press event of key.
690eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Otherwise bind fun to any key-press.
691eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Canvas must have focus. See method listen.
692eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
693eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if fun is None:
694eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            if key is None:
695eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                self.cv.unbind("<KeyPress>", None)
696eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            else:
697eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                self.cv.unbind("<KeyPress-%s>" % key, None)
698eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        else:
699eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            def eventfun(event):
700eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                fun()
701eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            if key is None:
702eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                self.cv.bind("<KeyPress>", eventfun)
703eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            else:
704eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                self.cv.bind("<KeyPress-%s>" % key, eventfun)
705eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
70697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _listen(self):
70797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set focus on canvas (in order to collect key-events)
70897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
70997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.focus_force()
71097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
71197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _ontimer(self, fun, t):
71297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Install a timer, which calls fun after t milliseconds.
71397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
71497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if t == 0:
71597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.after_idle(fun)
71697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
71797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.after(t, fun)
71897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
71997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _createimage(self, image):
72097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Create and return image item on canvas.
72197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
72297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.cv.create_image(0, 0, image=image)
72397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
72497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _drawimage(self, item, pos, image):
72597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Configure image item as to draw image object
72697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        at position (x,y) on canvas)
72797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
72897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x, y = pos
72997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.coords(item, (x * self.xscale, -y * self.yscale))
73097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.itemconfig(item, image=image)
73197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
73297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _setbgpic(self, item, image):
73397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Configure image item as to draw image object
73497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        at center of canvas. Set item to the first item
73597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        in the displaylist, so it will be drawn below
73697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        any other item ."""
73797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.itemconfig(item, image=image)
73897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.tag_lower(item)
73997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
74097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _type(self, item):
74197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return 'line' or 'polygon' or 'image' depending on
74297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        type of item.
74397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
74497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.cv.type(item)
74597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
74697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _pointlist(self, item):
74797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """returns list of coordinate-pairs of points of item
74897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for insiders):
74997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> from turtle import *
75097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> getscreen()._pointlist(getturtle().turtle._item)
75197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        [(0.0, 9.9999999999999982), (0.0, -9.9999999999999982),
75297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (9.9999999999999982, 0.0)]
75397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> """
75497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cl = list(self.cv.coords(item))
75597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pl = [(cl[i], -cl[i+1]) for i in range(0, len(cl), 2)]
75697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return  pl
75797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
75897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _setscrollregion(self, srx1, sry1, srx2, sry2):
75997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.config(scrollregion=(srx1, sry1, srx2, sry2))
76097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
76197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _rescale(self, xscalefactor, yscalefactor):
76297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        items = self.cv.find_all()
76397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for item in items:
76497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            coordinates = list(self.cv.coords(item))
76597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            newcoordlist = []
76697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            while coordinates:
76797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                x, y = coordinates[:2]
76897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                newcoordlist.append(x * xscalefactor)
76997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                newcoordlist.append(y * yscalefactor)
77097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                coordinates = coordinates[2:]
77197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.coords(item, *newcoordlist)
77297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
77397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _resize(self, canvwidth=None, canvheight=None, bg=None):
774f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        """Resize the canvas the turtles are drawing on. Does
77597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        not alter the drawing window.
77697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
77797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # needs amendment
77897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not isinstance(self.cv, ScrolledCanvas):
77997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self.canvwidth, self.canvheight
780fd1b0930ce6a84096d30c03a70cd9e0ee4a3178fFlorent Xicluna        if canvwidth is canvheight is bg is None:
78197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self.cv.canvwidth, self.cv.canvheight
78297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if canvwidth is not None:
78397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.canvwidth = canvwidth
78497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if canvheight is not None:
78597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.canvheight = canvheight
78697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.reset(canvwidth, canvheight, bg)
78797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
78897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _window_size(self):
78997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return the width and height of the turtle window.
79097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
79197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        width = self.cv.winfo_width()
79297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if width <= 1:  # the window isn't managed by a geometry manager
79397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            width = self.cv['width']
79497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        height = self.cv.winfo_height()
79597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if height <= 1: # the window isn't managed by a geometry manager
79697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            height = self.cv['height']
79797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return width, height
79897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
799eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def mainloop(self):
800eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Starts event loop - calling Tkinter's mainloop function.
801eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
802eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        No argument.
803eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
804eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Must be last statement in a turtle graphics program.
805eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Must NOT be used if a script is run from within IDLE in -n mode
806eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        (No subprocess) - for interactive use of turtle graphics.
807eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
808eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Example (for a TurtleScreen instance named screen):
809eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> screen.mainloop()
810eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
811eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
812eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        TK.mainloop()
813eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
814eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def textinput(self, title, prompt):
815eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Pop up a dialog window for input of a string.
816eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
817eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Arguments: title is the title of the dialog window,
818eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        prompt is a text mostly describing what information to input.
819eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
820eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Return the string input
821eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        If the dialog is canceled, return None.
822eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
823eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Example (for a TurtleScreen instance named screen):
824eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> screen.textinput("NIM", "Name of first player:")
825eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
826eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
827eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        return simpledialog.askstring(title, prompt)
828eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
829eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def numinput(self, title, prompt, default=None, minval=None, maxval=None):
830eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Pop up a dialog window for input of a number.
831eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
832eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Arguments: title is the title of the dialog window,
833eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        prompt is a text mostly describing what numerical information to input.
834eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        default: default value
835eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        minval: minimum value for imput
836eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        maxval: maximum value for input
837eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
838eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        The number input must be in the range minval .. maxval if these are
839eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        given. If not, a hint is issued and the dialog remains open for
840eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        correction. Return the number input.
841eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        If the dialog is canceled,  return None.
842eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
843eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Example (for a TurtleScreen instance named screen):
844eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> screen.numinput("Poker", "Your stakes:", 1000, minval=10, maxval=10000)
845eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
846eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
847eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        return simpledialog.askfloat(title, prompt, initialvalue=default,
848eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                                     minvalue=minval, maxvalue=maxval)
849eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
85097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
85197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis##############################################################################
85297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis###                  End of Tkinter - interface                            ###
85397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis##############################################################################
85497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
85597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
85697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass Terminator (Exception):
85797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Will be raised in TurtleScreen.update, if _RUNNING becomes False.
85897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
85997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Thus stops execution of turtle graphics script. Main purpose: use in
86097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    in the Demo-Viewer turtle.Demo.py.
86197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
8624b6ea798cbb6ef6058d97794c652e4acfd2ac165Martin v. Löwis    pass
863b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
864b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
86597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass TurtleGraphicsError(Exception):
86697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Some TurtleGraphics Error
86797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
86897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
86997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
87097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass Shape(object):
87197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Data structure modeling shapes.
87297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
87397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    attribute _type is one of "polygon", "image", "compound"
87497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    attribute _data is - depending on _type a poygon-tuple,
87597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    an image or a list constructed using the addcomponent method.
87697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
87797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, type_, data=None):
87897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._type = type_
87997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if type_ == "polygon":
88097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if isinstance(data, list):
88197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                data = tuple(data)
88297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif type_ == "image":
88397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if isinstance(data, str):
88497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if data.lower().endswith(".gif") and isfile(data):
88597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    data = TurtleScreen._image(data)
88697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                # else data assumed to be Photoimage
88797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif type_ == "compound":
88897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            data = []
88997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
89097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("There is no shape type %s" % type_)
89197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._data = data
89297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
89397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def addcomponent(self, poly, fill, outline=None):
89497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Add component to a shape of type compound.
89597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
89697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments: poly is a polygon, i. e. a tuple of number pairs.
89797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fill is the fillcolor of the component,
89897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        outline is the outline color of the component.
89997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
90097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        call (for a Shapeobject namend s):
90197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --   s.addcomponent(((0,0), (10,10), (-10,10)), "red", "blue")
90297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
90397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example:
90497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
90597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> s = Shape("compound")
90697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> s.addcomponent(poly, "red", "blue")
90797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ### .. add more components and then use register_shape()
90897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
90997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._type != "compound":
91097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("Cannot add component to %s Shape"
91197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                                % self._type)
91297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if outline is None:
91397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            outline = fill
91497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._data.append([poly, fill, outline])
91597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
91697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
91797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass Tbuffer(object):
91897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Ring buffer used as undobuffer for RawTurtle objects."""
91997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, bufsize=10):
92097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.bufsize = bufsize
92197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.buffer = [[None]] * bufsize
92297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.ptr = -1
92397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cumulate = False
92497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def reset(self, bufsize=None):
92597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if bufsize is None:
92697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for i in range(self.bufsize):
92797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.buffer[i] = [None]
92897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
92997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.bufsize = bufsize
93097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.buffer = [[None]] * bufsize
93197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.ptr = -1
93297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def push(self, item):
93397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.bufsize > 0:
93497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if not self.cumulate:
93597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.ptr = (self.ptr + 1) % self.bufsize
93697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.buffer[self.ptr] = item
93797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
93897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.buffer[self.ptr].append(item)
93997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def pop(self):
94097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.bufsize > 0:
94197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            item = self.buffer[self.ptr]
94297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if item is None:
94397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                return None
94497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
94597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.buffer[self.ptr] = [None]
94697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.ptr = (self.ptr - 1) % self.bufsize
94797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                return (item)
94897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def nr_of_items(self):
94997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.bufsize - self.buffer.count([None])
95097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __repr__(self):
95197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return str(self.buffer) + " " + str(self.ptr)
95297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
95397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
95497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
95597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass TurtleScreen(TurtleScreenBase):
95697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Provides screen oriented methods like setbg etc.
95797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
95897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Only relies upon the methods of TurtleScreenBase and NOT
95997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    upon components of the underlying graphics toolkit -
96097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    which is Tkinter in this case.
96197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
96297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _RUNNING = True
96397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
96497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, cv, mode=_CFG["mode"],
96597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 colormode=_CFG["colormode"], delay=_CFG["delay"]):
96697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._shapes = {
96797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                   "arrow" : Shape("polygon", ((-10,0), (10,0), (0,10))),
96897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                  "turtle" : Shape("polygon", ((0,16), (-2,14), (-1,10), (-4,7),
96997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (-7,9), (-9,8), (-6,5), (-7,1), (-5,-3), (-8,-6),
97097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (-6,-8), (-4,-5), (0,-7), (4,-5), (6,-8), (8,-6),
97197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (5,-3), (7,1), (6,5), (9,8), (7,9), (4,7), (1,10),
97297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (2,14))),
97397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                  "circle" : Shape("polygon", ((10,0), (9.51,3.09), (8.09,5.88),
97497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (5.88,8.09), (3.09,9.51), (0,10), (-3.09,9.51),
97597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (-5.88,8.09), (-8.09,5.88), (-9.51,3.09), (-10,0),
97697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (-9.51,-3.09), (-8.09,-5.88), (-5.88,-8.09),
97797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (-3.09,-9.51), (-0.00,-10.00), (3.09,-9.51),
97897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (5.88,-8.09), (8.09,-5.88), (9.51,-3.09))),
97997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                  "square" : Shape("polygon", ((10,-10), (10,10), (-10,10),
98097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (-10,-10))),
98197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "triangle" : Shape("polygon", ((10,-5.77), (0,11.55),
98297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (-10,-5.77))),
98397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                  "classic": Shape("polygon", ((0,0),(-5,-9),(0,-7),(5,-9))),
98497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                   "blank" : Shape("image", self._blankimage())
98597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                  }
98697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
98797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._bgpics = {"nopic" : ""}
98897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
98997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TurtleScreenBase.__init__(self, cv)
99097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._mode = mode
99197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._delayvalue = delay
99297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._colormode = _CFG["colormode"]
99397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._keys = []
99497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.clear()
99597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
99697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def clear(self):
99797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Delete all drawings and all turtles from the TurtleScreen.
99897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
999eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        No argument.
1000eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
1001f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        Reset empty TurtleScreen to its initial state: white background,
100297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        no backgroundimage, no eventbindings and tracing on.
100397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
100497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
100597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen.clear()
100697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
100797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Note: this method is not available as function.
100897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
100997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._delayvalue = _CFG["delay"]
101097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._colormode = _CFG["colormode"]
101197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._delete("all")
101297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._bgpic = self._createimage("")
101397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._bgpicname = "nopic"
1014b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum        self._tracing = 1
101597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._updatecounter = 0
101697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._turtles = []
101797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.bgcolor("white")
101897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for btn in 1, 2, 3:
101997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.onclick(None, btn)
1020eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self.onkeypress(None)
102197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for key in self._keys[:]:
102297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.onkey(None, key)
1023eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            self.onkeypress(None, key)
102497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Turtle._pen = None
102597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
102697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def mode(self, mode=None):
102797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set turtle-mode ('standard', 'logo' or 'world') and perform reset.
102897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
102997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
103097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        mode -- on of the strings 'standard', 'logo' or 'world'
103197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
103297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Mode 'standard' is compatible with turtle.py.
103397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Mode 'logo' is compatible with most Logo-Turtle-Graphics.
103497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Mode 'world' uses userdefined 'worldcoordinates'. *Attention*: in
103597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        this mode angles appear distorted if x/y unit-ratio doesn't equal 1.
103697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If mode is not given, return the current mode.
103797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
103897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis             Mode      Initial turtle heading     positive angles
103997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis         ------------|-------------------------|-------------------
104097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          'standard'    to the right (east)       counterclockwise
104197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            'logo'        upward    (north)         clockwise
104297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
104397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples:
104497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> mode('logo')   # resets turtle heading to north
104597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> mode()
104697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'logo'
104797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
1048fd1b0930ce6a84096d30c03a70cd9e0ee4a3178fFlorent Xicluna        if mode is None:
104997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._mode
105097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        mode = mode.lower()
105197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if mode not in ["standard", "logo", "world"]:
105297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("No turtle-graphics-mode %s" % mode)
105397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._mode = mode
105497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if mode in ["standard", "logo"]:
105597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._setscrollregion(-self.canvwidth//2, -self.canvheight//2,
105697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                       self.canvwidth//2, self.canvheight//2)
105797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.xscale = self.yscale = 1.0
1058b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum        self.reset()
1059b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
106097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def setworldcoordinates(self, llx, lly, urx, ury):
106197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set up a user defined coordinate-system.
106297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
106397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
106497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        llx -- a number, x-coordinate of lower left corner of canvas
106597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        lly -- a number, y-coordinate of lower left corner of canvas
106697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        urx -- a number, x-coordinate of upper right corner of canvas
106797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ury -- a number, y-coordinate of upper right corner of canvas
106897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
106997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set up user coodinat-system and switch to mode 'world' if necessary.
107097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        This performs a screen.reset. If mode 'world' is already active,
107197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        all drawings are redrawn according to the new coordinates.
107297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
107397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        But ATTENTION: in user-defined coordinatesystems angles may appear
107497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        distorted. (see Screen.mode())
107597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
107697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
107797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.setworldcoordinates(-10,-0.5,50,1.5)
107897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> for _ in range(36):
107997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                left(10)
108097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                forward(0.5)
108197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
108297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.mode() != "world":
108397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.mode("world")
108497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        xspan = float(urx - llx)
108597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        yspan = float(ury - lly)
108697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        wx, wy = self._window_size()
108797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screensize(wx-20, wy-20)
108897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        oldxscale, oldyscale = self.xscale, self.yscale
108997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.xscale = self.canvwidth / xspan
109097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.yscale = self.canvheight / yspan
109197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        srx1 = llx * self.xscale
109297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        sry1 = -ury * self.yscale
109397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        srx2 = self.canvwidth + srx1
109497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        sry2 = self.canvheight + sry1
109597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._setscrollregion(srx1, sry1, srx2, sry2)
109697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._rescale(self.xscale/oldxscale, self.yscale/oldyscale)
109797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.update()
109897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
109997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def register_shape(self, name, shape=None):
110097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Adds a turtle shape to TurtleScreen's shapelist.
110197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
110297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
110397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (1) name is the name of a gif-file and shape is None.
110497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            Installs the corresponding image shape.
110597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            !! Image-shapes DO NOT rotate when turning the turtle,
110697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            !! so they do not display the heading of the turtle!
110797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (2) name is an arbitrary string and shape is a tuple
110897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            of pairs of coordinates. Installs the corresponding
110997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            polygon shape
111097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (3) name is an arbitrary string and shape is a
111197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            (compound) Shape object. Installs the corresponding
111297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            compound shape.
111397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        To use a shape, you have to issue the command shape(shapename).
111497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
111597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        call: register_shape("turtle.gif")
111697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: register_shape("tri", ((0,0), (10,10), (-10,10)))
111797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
111897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
111997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.register_shape("triangle", ((5,-3),(0,5),(-5,-3)))
112097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
112197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
112297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if shape is None:
112397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            # image
112497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if name.lower().endswith(".gif"):
112597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                shape = Shape("image", self._image(name))
112697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
112797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                raise TurtleGraphicsError("Bad arguments for register_shape.\n"
112897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                          + "Use  help(register_shape)" )
112997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif isinstance(shape, tuple):
113097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            shape = Shape("polygon", shape)
113197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ## else shape assumed to be Shape-instance
113297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._shapes[name] = shape
113397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
113497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _colorstr(self, color):
113597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return color string corresponding to args.
113697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
113797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument may be a string or a tuple of three
113897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        numbers corresponding to actual colormode,
113997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        i.e. in the range 0<=n<=colormode.
114097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
114197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If the argument doesn't represent a color,
114297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        an error is raised.
114397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
114497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if len(color) == 1:
114597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            color = color[0]
114697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(color, str):
114797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._iscolorstring(color) or color == "":
114897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                return color
114997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
115097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                raise TurtleGraphicsError("bad color string: %s" % str(color))
115197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        try:
115297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            r, g, b = color
115397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        except:
115497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("bad color arguments: %s" % str(color))
115597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._colormode == 1.0:
115697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            r, g, b = [round(255.0*x) for x in (r, g, b)]
115797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)):
115897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("bad color sequence: %s" % str(color))
115997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return "#%02x%02x%02x" % (r, g, b)
116097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
116197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _color(self, cstr):
116297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not cstr.startswith("#"):
116397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return cstr
116497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if len(cstr) == 7:
116597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            cl = [int(cstr[i:i+2], 16) for i in (1, 3, 5)]
116697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif len(cstr) == 4:
116797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            cl = [16*int(cstr[h], 16) for h in cstr[1:]]
116897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
116997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("bad colorstring: %s" % cstr)
117097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return tuple([c * self._colormode/255 for c in cl])
117197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
117297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def colormode(self, cmode=None):
117397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the colormode or set it to 1.0 or 255.
117497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
117597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
117697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cmode -- one of the values 1.0 or 255
117797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
117897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        r, g, b values of colortriples have to be in range 0..cmode.
117997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
118097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
118197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.colormode()
118297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        1.0
118397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.colormode(255)
118497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pencolor(240,160,80)
118597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
118697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if cmode is None:
118797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._colormode
118897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if cmode == 1.0:
118997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._colormode = float(cmode)
119097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif cmode == 255:
119197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._colormode = int(cmode)
119297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
119397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def reset(self):
119497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Reset all Turtles on the Screen to their initial state.
119597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
119697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
119797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
119897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
119997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.reset()
120097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
120197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for turtle in self._turtles:
120297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            turtle._setmode(self._mode)
120397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            turtle.reset()
120497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
120597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def turtles(self):
120697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the list of turtles on the screen.
120797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
120897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
120997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.turtles()
121097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        [<turtle.Turtle object at 0x00E11FB0>]
121197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
121297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._turtles
121397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
121497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def bgcolor(self, *args):
121597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set or return backgroundcolor of the TurtleScreen.
121697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
121797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments (if given): a color string or three numbers
121897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        in the range 0..colormode or a 3-tuple of such numbers.
121997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
122097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
122197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bgcolor("orange")
122297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bgcolor()
122397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'orange'
122497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bgcolor(0.5,0,0.5)
122597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bgcolor()
122697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        '#800080'
122797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
122897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if args:
122997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            color = self._colorstr(args)
123097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
123197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            color = None
123297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color = self._bgcolor(color)
123397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if color is not None:
123497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            color = self._color(color)
123597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return color
123697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
123797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def tracer(self, n=None, delay=None):
123897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Turns turtle animation on/off and set delay for update drawings.
123997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
124097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional arguments:
124197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        n -- nonnegative  integer
124297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        delay -- nonnegative  integer
124397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
124497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If n is given, only each n-th regular screen update is really performed.
124597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (Can be used to accelerate the drawing of complex graphics.)
124697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Second arguments sets delay value (see RawTurtle.delay())
124797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
124897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
124997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.tracer(8, 25)
125097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> dist = 2
125197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> for i in range(200):
125297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fd(dist)
125397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                rt(90)
125497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                dist += 2
125597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
125697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if n is None:
125797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._tracing
125897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._tracing = int(n)
125997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._updatecounter = 0
126097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if delay is not None:
126197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._delayvalue = int(delay)
126297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._tracing:
126397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.update()
126497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
126597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def delay(self, delay=None):
126697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return or set the drawing delay in milliseconds.
126797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
126897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
126997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        delay -- positive integer
127097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
127197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
127297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.delay(15)
127397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.delay()
127497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        15
127597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
127697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if delay is None:
127797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._delayvalue
127897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._delayvalue = int(delay)
127997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
128097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _incrementudc(self):
128197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "Increment upadate counter."""
128297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not TurtleScreen._RUNNING:
128397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            TurtleScreen._RUNNNING = True
128497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise Terminator
128597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._tracing > 0:
128697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._updatecounter += 1
128797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._updatecounter %= self._tracing
128897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
128997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def update(self):
129097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Perform a TurtleScreen update.
129197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
1292eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        tracing = self._tracing
1293eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._tracing = True
129497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for t in self.turtles():
129597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            t._update_data()
129697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            t._drawturtle()
1297eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._tracing = tracing
129897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
129997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
130097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def window_width(self):
130197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return the width of the turtle window.
130297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
130397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
130497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.window_width()
130597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        640
130697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
130797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._window_size()[0]
130897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
130997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def window_height(self):
131097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return the height of the turtle window.
131197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
131297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
131397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.window_height()
131497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        480
131597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
131697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._window_size()[1]
131797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
131897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def getcanvas(self):
131997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the Canvas of this TurtleScreen.
132097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
132197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
132297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
132397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Screen instance named screen):
132497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> cv = screen.getcanvas()
132597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> cv
132697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        <turtle.ScrolledCanvas instance at 0x010742D8>
132797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
132897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.cv
132997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
133097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def getshapes(self):
133197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return a list of names of all currently available turtle shapes.
133297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
133397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
133497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
133597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
133697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.getshapes()
133797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ['arrow', 'blank', 'circle', ... , 'turtle']
133897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
133997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return sorted(self._shapes.keys())
134097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
134197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def onclick(self, fun, btn=1, add=None):
134297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-click event on canvas.
134397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
134497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
134597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun -- a function with two arguments, the coordinates of the
134697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis               clicked point on the canvas.
134797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num -- the number of the mouse-button, defaults to 1
134897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
134997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen
135097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        and a Turtle instance named turtle):
135197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
135297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.onclick(turtle.goto)
135397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
135497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ### Subsequently clicking into the TurtleScreen will
135597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ### make the turtle move to the clicked point.
135697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.onclick(None)
135797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
135897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ### event-binding will be removed
135997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
136097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._onscreenclick(fun, btn, add)
136197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
136297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def onkey(self, fun, key):
136397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to key-release event of key.
136497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
136597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
136697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun -- a function with no arguments
136797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        key -- a string: key (e.g. "a") or key-symbol (e.g. "space")
136897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
1369f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        In order to be able to register key-events, TurtleScreen
137097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        must have focus. (See method listen.)
137197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
137297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen
137397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        and a Turtle instance named turtle):
137497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
137597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> def f():
137697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fd(50)
137797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                lt(60)
137897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
137997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
138097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.onkey(f, "Up")
138197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.listen()
138297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
138397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ### Subsequently the turtle can be moved by
138497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ### repeatedly pressing the up-arrow key,
138597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ### consequently drawing a hexagon
138697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
1387fd1b0930ce6a84096d30c03a70cd9e0ee4a3178fFlorent Xicluna        if fun is None:
1388eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            if key in self._keys:
1389eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                self._keys.remove(key)
139097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif key not in self._keys:
139197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._keys.append(key)
1392eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._onkeyrelease(fun, key)
1393eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
1394eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def onkeypress(self, fun, key=None):
1395eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Bind fun to key-press event of key if key is given,
1396eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        or to any key-press-event if no key is given.
1397eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
1398eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Arguments:
1399eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        fun -- a function with no arguments
1400eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        key -- a string: key (e.g. "a") or key-symbol (e.g. "space")
1401eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
1402eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        In order to be able to register key-events, TurtleScreen
1403eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        must have focus. (See method listen.)
1404eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
1405eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Example (for a TurtleScreen instance named screen
1406eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        and a Turtle instance named turtle):
1407eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
1408eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> def f():
1409eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                fd(50)
1410eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
1411eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
1412eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> screen.onkey(f, "Up")
1413eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> screen.listen()
1414eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
1415eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        ### Subsequently the turtle can be moved by
1416eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        ### repeatedly pressing the up-arrow key,
1417eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        ### or by keeping pressed the up-arrow key.
1418eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        ### consequently drawing a hexagon.
1419eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
1420fd1b0930ce6a84096d30c03a70cd9e0ee4a3178fFlorent Xicluna        if fun is None:
1421eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            if key in self._keys:
1422eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                self._keys.remove(key)
1423eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        elif key is not None and key not in self._keys:
1424eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            self._keys.append(key)
1425eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._onkeypress(fun, key)
142697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
142797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def listen(self, xdummy=None, ydummy=None):
142897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set focus on TurtleScreen (in order to collect key-events)
142997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
143097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
143197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Dummy arguments are provided in order
143297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        to be able to pass listen to the onclick method.
143397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
143497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
143597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.listen()
143697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
143797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._listen()
143897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
143997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def ontimer(self, fun, t=0):
144097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Install a timer, which calls fun after t milliseconds.
144197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
144297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
144397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun -- a function with no arguments.
144497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        t -- a number >= 0
144597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
144697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
144797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
144897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> running = True
144997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> def f():
145097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if running:
145197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                        fd(50)
145297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                        lt(60)
145397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                        screen.ontimer(f, 250)
145497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
145597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> f()   ### makes the turtle marching around
145697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> running = False
145797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
145897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._ontimer(fun, t)
145997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
146097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def bgpic(self, picname=None):
146197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set background image or return name of current backgroundimage.
146297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
146397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
146497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        picname -- a string, name of a gif-file or "nopic".
146597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
146697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If picname is a filename, set the corresponing image as background.
146797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If picname is "nopic", delete backgroundimage, if present.
146897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If picname is None, return the filename of the current backgroundimage.
146997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
147097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
147197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bgpic()
147297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'nopic'
147397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bgpic("landscape.gif")
147497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bgpic()
147597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'landscape.gif'
147697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
147797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if picname is None:
147897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._bgpicname
147997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if picname not in self._bgpics:
148097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._bgpics[picname] = self._image(picname)
148197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._setbgpic(self._bgpic, self._bgpics[picname])
148297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._bgpicname = picname
148397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
148497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def screensize(self, canvwidth=None, canvheight=None, bg=None):
1485f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        """Resize the canvas the turtles are drawing on.
148697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
148797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional arguments:
148897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        canvwidth -- positive integer, new width of canvas in pixels
148997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        canvheight --  positive integer, new height of canvas in pixels
149097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        bg -- colorstring or color-tupel, new backgroundcolor
149197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If no arguments are given, return current (canvaswidth, canvasheight)
149297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
149397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Do not alter the drawing window. To observe hidden parts of
149497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        the canvas use the scrollbars. (Can make visible those parts
149597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of a drawing, which were outside the canvas before!)
149697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
149797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
149897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.screensize(2000,1500)
149997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            ### e. g. to search for an erroneously escaped turtle ;-)
150097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
150197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._resize(canvwidth, canvheight, bg)
150297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
150397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    onscreenclick = onclick
150497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    resetscreen = reset
150597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    clearscreen = clear
150697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    addshape = register_shape
1507eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    onkeyrelease = onkey
150897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
150997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass TNavigator(object):
151097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Navigation part of the RawTurtle.
151197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Implements methods for turtle movement.
151297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
151397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    START_ORIENTATION = {
151497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "standard": Vec2D(1.0, 0.0),
151597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "world"   : Vec2D(1.0, 0.0),
151697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "logo"    : Vec2D(0.0, 1.0)  }
151797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    DEFAULT_MODE = "standard"
151897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    DEFAULT_ANGLEOFFSET = 0
151997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    DEFAULT_ANGLEORIENT = 1
152097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
152197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, mode=DEFAULT_MODE):
152297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._angleOffset = self.DEFAULT_ANGLEOFFSET
152397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._angleOrient = self.DEFAULT_ANGLEORIENT
152497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._mode = mode
152597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.undobuffer = None
152697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.degrees()
152797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._mode = None
152897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._setmode(mode)
152997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TNavigator.reset(self)
153097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
153197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def reset(self):
153297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """reset turtle to its initial values
153397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
153497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Will be overwritten by parent class
153597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
153697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._position = Vec2D(0.0, 0.0)
153797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._orient =  TNavigator.START_ORIENTATION[self._mode]
153897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
153997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _setmode(self, mode=None):
154097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set turtle-mode to 'standard', 'world' or 'logo'.
154197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
1542fd1b0930ce6a84096d30c03a70cd9e0ee4a3178fFlorent Xicluna        if mode is None:
154397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._mode
154497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if mode not in ["standard", "logo", "world"]:
154597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
154697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._mode = mode
154797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if mode in ["standard", "world"]:
154897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._angleOffset = 0
154997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._angleOrient = 1
155097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else: # mode == "logo":
155197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._angleOffset = self._fullcircle/4.
155297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._angleOrient = -1
155397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
155497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _setDegreesPerAU(self, fullcircle):
155597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Helper function for degrees() and radians()"""
155697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._fullcircle = fullcircle
155797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._degreesPerAU = 360/fullcircle
155897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._mode == "standard":
155997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._angleOffset = 0
156097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
156197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._angleOffset = fullcircle/4.
156297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
1563b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum    def degrees(self, fullcircle=360.0):
1564477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """ Set angle measurement units to degrees.
1565477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
156697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
156797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fullcircle -  a number
156897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
156997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set angle measurement units, i. e. set number
157097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of 'degrees' for a full circle. Dafault value is
157197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        360 degrees.
157297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
157397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
157497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.left(90)
157597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
157697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        90
157797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.degrees(400.0)  # angle measurement in gon
157897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
157997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        100
158097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
158197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
158297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._setDegreesPerAU(fullcircle)
158397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
158497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def radians(self):
158597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Set the angle measurement units to radians.
158697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
158797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
158897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
158997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
159097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
159197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        90
159297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.radians()
159397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
159497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        1.5707963267948966
159597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
159697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._setDegreesPerAU(2*math.pi)
159797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
159897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _go(self, distance):
159997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """move turtle forward by specified distance"""
160097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ende = self._position + self._orient * distance
160197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._goto(ende)
160297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
160397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _rotate(self, angle):
160497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Turn turtle counterclockwise by specified angle if angle > 0."""
160597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle *= self._degreesPerAU
160697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._orient = self._orient.rotate(angle)
160797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
160897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _goto(self, end):
160997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """move turtle to position end."""
161097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._position = end
161197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
161297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def forward(self, distance):
161397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Move the turtle forward by the specified distance.
161497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
161597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: forward | fd
161697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
161797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
161897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        distance -- a number (integer or float)
161997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
162097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Move the turtle forward by the specified distance, in the direction
162197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        the turtle is headed.
162297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
162397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
162497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
162597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, 0.00)
162697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.forward(25)
162797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
162897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (25.00,0.00)
162997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.forward(-75)
163097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
163197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (-50.00,0.00)
163297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
163397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._go(distance)
163497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
163597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def back(self, distance):
163697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Move the turtle backward by distance.
163797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
163897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: back | backward | bk
163997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
164097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
164197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        distance -- a number
164297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
164397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Move the turtle backward by distance ,opposite to the direction the
164497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle is headed. Do not change the turtle's heading.
164597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
164697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
164797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
164897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, 0.00)
164997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.backward(30)
165097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
165197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (-30.00, 0.00)
165297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
165397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._go(-distance)
165497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
165597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def right(self, angle):
165697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Turn turtle right by angle units.
165797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
165897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: right | rt
165997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
166097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
166197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle -- a number (integer or float)
166297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
166397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Turn turtle right by angle units. (Units are by default degrees,
166497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        but can be set via the degrees() and radians() functions.)
166597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Angle orientation depends on mode. (See this.)
166697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
166797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
166897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
166997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        22.0
167097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.right(45)
167197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
167297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        337.0
167397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
167497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._rotate(-angle)
167597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
167697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def left(self, angle):
167797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Turn turtle left by angle units.
167897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
167997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: left | lt
168097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
168197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
168297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle -- a number (integer or float)
168397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
168497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Turn turtle left by angle units. (Units are by default degrees,
168597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        but can be set via the degrees() and radians() functions.)
168697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Angle orientation depends on mode. (See this.)
168797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
168897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
168997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
169097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        22.0
169197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.left(45)
169297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
169397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        67.0
169497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
169597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._rotate(angle)
169697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
169797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def pos(self):
169897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the turtle's current location (x,y), as a Vec2D-vector.
169997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
170097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: pos | position
170197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
170297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
170397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
170497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
170597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pos()
170697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, 240.00)
170797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
170897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._position
170997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
171097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def xcor(self):
171197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return the turtle's x coordinate.
171297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
171397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
171497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
171597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
171697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> reset()
171797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.left(60)
171897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.forward(100)
171997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> print turtle.xcor()
172097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        50.0
172197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
172297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._position[0]
172397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
172497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def ycor(self):
172597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return the turtle's y coordinate
172697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ---
172797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
172897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
172997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
173097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> reset()
173197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.left(60)
173297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.forward(100)
173397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> print turtle.ycor()
173497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        86.6025403784
173597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
173697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._position[1]
173797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
173897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
173997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def goto(self, x, y=None):
174097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Move turtle to an absolute position.
174197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
174297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: setpos | setposition | goto:
174397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
174497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
174597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x -- a number      or     a pair/vector of numbers
174697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        y -- a number             None
174797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
174897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        call: goto(x, y)         # two coordinates
174997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: goto((x, y))       # a pair (tuple) of coordinates
175097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: goto(vec)          # e.g. as returned by pos()
175197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
175297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Move turtle to an absolute position. If the pen is down,
175397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        a line will be drawn. The turtle's orientation does not change.
175497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
175597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
175697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> tp = turtle.pos()
175797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> tp
175897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, 0.00)
175997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.setpos(60,30)
176097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pos()
176197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (60.00,30.00)
176297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.setpos((20,80))
176397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pos()
176497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (20.00,80.00)
176597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.setpos(tp)
176697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pos()
176797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00,0.00)
176897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
176997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if y is None:
177097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._goto(Vec2D(*x))
177197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
177297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._goto(Vec2D(x, y))
177397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
177497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def home(self):
177597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Move turtle to the origin - coordinates (0,0).
177697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
177797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
177897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
1779f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        Move turtle to the origin - coordinates (0,0) and set its
1780f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        heading to its start-orientation (which depends on mode).
178197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
178297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
178397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.home()
178497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
178597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.goto(0, 0)
178697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.setheading(0)
178797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
178897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def setx(self, x):
178997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set the turtle's first coordinate to x
179097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
179197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
179297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x -- a number (integer or float)
179397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
179497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set the turtle's first coordinate to x, leave second coordinate
179597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        unchanged.
179697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
179797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
179897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
179997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, 240.00)
180097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.setx(10)
180197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
180297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (10.00, 240.00)
180397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
180497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._goto(Vec2D(x, self._position[1]))
180597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
180697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def sety(self, y):
180797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set the turtle's second coordinate to y
180897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
180997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
181097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        y -- a number (integer or float)
181197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
181297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set the turtle's first coordinate to x, second coordinate remains
181397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        unchanged.
181497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
181597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
181697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
181797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, 40.00)
181897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.sety(-10)
181997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
182097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, -10.00)
182197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
182297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._goto(Vec2D(self._position[0], y))
182397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
182497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def distance(self, x, y=None):
182597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the distance from the turtle to (x,y) in turtle step units.
182697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
182797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
182897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x -- a number   or  a pair/vector of numbers   or   a turtle instance
182997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        y -- a number       None                            None
183097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
183197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        call: distance(x, y)         # two coordinates
183297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: distance((x, y))       # a pair (tuple) of coordinates
183397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: distance(vec)          # e.g. as returned by pos()
183497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: distance(mypen)        # where mypen is another turtle
183597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
183697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
183797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pos()
183897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, 0.00)
183997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.distance(30,40)
184097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        50.0
184197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> pen = Turtle()
184297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> pen.forward(77)
184397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.distance(pen)
184497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        77.0
184597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
184697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if y is not None:
184797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = Vec2D(x, y)
184897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(x, Vec2D):
184997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = x
185097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif isinstance(x, tuple):
185197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = Vec2D(*x)
185297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif isinstance(x, TNavigator):
185397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = x._position
185497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return abs(pos - self._position)
185597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
185697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def towards(self, x, y=None):
185797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the angle of the line from the turtle's position to (x, y).
185897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
185997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
186097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x -- a number   or  a pair/vector of numbers   or   a turtle instance
186197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        y -- a number       None                            None
186297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
186397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        call: distance(x, y)         # two coordinates
186497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: distance((x, y))       # a pair (tuple) of coordinates
186597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: distance(vec)          # e.g. as returned by pos()
186697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: distance(mypen)        # where mypen is another turtle
186797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
186897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Return the angle, between the line from turtle-position to position
186997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        specified by x, y and the turtle's start orientation. (Depends on
187097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        modes - "standard" or "logo")
187197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
187297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
187397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pos()
187497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (10.00, 10.00)
187597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.towards(0,0)
187697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        225.0
187797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
187897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if y is not None:
187997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = Vec2D(x, y)
188097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(x, Vec2D):
188197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = x
188297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif isinstance(x, tuple):
188397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = Vec2D(*x)
188497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif isinstance(x, TNavigator):
188597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = x._position
188697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x, y = pos - self._position
188797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0
188897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        result /= self._degreesPerAU
188997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return (self._angleOffset + self._angleOrient*result) % self._fullcircle
189097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
189197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def heading(self):
189297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return the turtle's current heading.
189397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
189497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
189597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
189697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
189797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.left(67)
189897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
189997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        67.0
190097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
190197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x, y = self._orient
190297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0
190397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        result /= self._degreesPerAU
190497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return (self._angleOffset + self._angleOrient*result) % self._fullcircle
190597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
190697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def setheading(self, to_angle):
190797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set the orientation of the turtle to to_angle.
190897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
190997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases:  setheading | seth
191097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
191197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
191297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        to_angle -- a number (integer or float)
191397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
191497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set the orientation of the turtle to to_angle.
191597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Here are some common directions in degrees:
191697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
191797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis         standard - mode:          logo-mode:
191897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        -------------------|--------------------
191997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           0 - east                0 - north
192097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          90 - north              90 - east
192197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis         180 - west              180 - south
192297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis         270 - south             270 - west
192397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
192497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
192597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.setheading(90)
192697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
192797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        90
192897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
192997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle = (to_angle - self.heading())*self._angleOrient
193097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        full = self._fullcircle
193197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle = (angle+full/2.)%full - full/2.
193297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._rotate(angle)
193397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
193497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def circle(self, radius, extent = None, steps = None):
193597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Draw a circle with given radius.
193697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
193797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
193897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        radius -- a number
193997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        extent (optional) -- a number
194097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        steps (optional) -- an integer
194197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
194297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Draw a circle with given radius. The center is radius units left
194397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of the turtle; extent - an angle - determines which part of the
194497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        circle is drawn. If extent is not given, draw the entire circle.
194597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If extent is not a full circle, one endpoint of the arc is the
194697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        current pen position. Draw the arc in counterclockwise direction
194797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if radius is positive, otherwise in clockwise direction. Finally
194897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        the direction of the turtle is changed by the amount of extent.
194997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
195097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        As the circle is approximated by an inscribed regular polygon,
195197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        steps determines the number of steps to use. If not given,
195297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        it will be calculated automatically. Maybe used to draw regular
195397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        polygons.
195497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
195597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        call: circle(radius)                  # full circle
195697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: circle(radius, extent)          # arc
195797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: circle(radius, extent, steps)
195897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: circle(radius, steps=6)         # 6-sided polygon
195997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
196097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
196197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.circle(50)
196297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.circle(120, 180)  # semicircle
196397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
196497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
196597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.push(["seq"])
196697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.cumulate = True
196797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speed = self.speed()
196897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if extent is None:
196997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            extent = self._fullcircle
197097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if steps is None:
197197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            frac = abs(extent)/self._fullcircle
197297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
197397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        w = 1.0 * extent / steps
197497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        w2 = 0.5 * w
197597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        l = 2.0 * radius * math.sin(w2*math.pi/180.0*self._degreesPerAU)
197697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if radius < 0:
197797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            l, w, w2 = -l, -w, -w2
197897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tr = self._tracer()
197997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        dl = self._delay()
198097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if speed == 0:
198197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._tracer(0, 0)
198297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
198397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.speed(0)
198497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._rotate(w2)
198597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for i in range(steps):
198697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.speed(speed)
198797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._go(l)
198897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.speed(0)
198997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._rotate(w)
199097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._rotate(-w2)
199197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if speed == 0:
199297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._tracer(tr, dl)
199397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.speed(speed)
199497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
199597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.cumulate = False
199697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
199797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis## three dummy methods to be implemented by child class:
199897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
199997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def speed(self, s=0):
200097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """dummy method - to be overwritten by child class"""
200197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _tracer(self, a=None, b=None):
200297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """dummy method - to be overwritten by child class"""
200397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _delay(self, n=None):
200497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """dummy method - to be overwritten by child class"""
200597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
200697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    fd = forward
200797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    bk = back
200897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    backward = back
200997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    rt = right
201097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    lt = left
201197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    position = pos
201297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    setpos = goto
201397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    setposition = goto
201497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    seth = setheading
201597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
201697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
201797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass TPen(object):
201897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Drawing part of the RawTurtle.
201997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Implements drawing properties.
202097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
202197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, resizemode=_CFG["resizemode"]):
202297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._resizemode = resizemode # or "user" or "noresize"
202397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.undobuffer = None
202497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TPen._reset(self)
202597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
202697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _reset(self, pencolor=_CFG["pencolor"],
202797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                     fillcolor=_CFG["fillcolor"]):
202897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._pensize = 1
202997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._shown = True
203097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._pencolor = pencolor
203197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._fillcolor = fillcolor
203297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._drawing = True
203397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._speed = 3
2034eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._stretchfactor = (1., 1.)
2035eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._shearfactor = 0.
2036eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._tilt = 0.
2037eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._shapetrafo = (1., 0., 0., 1.)
203897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._outlinewidth = 1
203997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
204097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def resizemode(self, rmode=None):
204197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set resizemode to one of the values: "auto", "user", "noresize".
204297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
204397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (Optional) Argument:
204497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        rmode -- one of the strings "auto", "user", "noresize"
204597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
204697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Different resizemodes have the following effects:
204797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - "auto" adapts the appearance of the turtle
204897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                   corresponding to the value of pensize.
204997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - "user" adapts the appearance of the turtle according to the
205097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                   values of stretchfactor and outlinewidth (outline),
205197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                   which are set by shapesize()
205297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - "noresize" no adaption of the turtle's appearance takes place.
205397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If no argument is given, return current resizemode.
205497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        resizemode("user") is called by a call of shapesize with arguments.
205597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
205697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
205797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Turtle instance named turtle):
205897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.resizemode("noresize")
205997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.resizemode()
206097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'noresize'
206197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
206297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if rmode is None:
206397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._resizemode
206497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        rmode = rmode.lower()
206597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if rmode in ["auto", "user", "noresize"]:
206697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.pen(resizemode=rmode)
206797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
206897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def pensize(self, width=None):
206997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set or return the line thickness.
207097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
207197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases:  pensize | width
207297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
207397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
207497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        width -- positive number
207597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
207697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set the line thickness to width or return it. If resizemode is set
207797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        to "auto" and turtleshape is a polygon, that polygon is drawn with
207897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        the same line thickness. If no argument is given, current pensize
207997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        is returned.
208097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
208197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
208297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pensize()
208397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        1
208497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.pensize(10)   # from here on lines of width 10 are drawn
208597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
208697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if width is None:
208797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._pensize
208897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(pensize=width)
208997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
209097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
209197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def penup(self):
209297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Pull the pen up -- no drawing when moving.
209397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
209497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: penup | pu | up
209597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
209697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument
209797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
209897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
209997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.penup()
210097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
210197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not self._drawing:
210297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
210397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(pendown=False)
210497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
210597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def pendown(self):
210697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Pull the pen down -- drawing when moving.
210797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
210897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: pendown | pd | down
210997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
211097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
211197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
211297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
211397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pendown()
211497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
211597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._drawing:
211697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
211797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(pendown=True)
211897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
211997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def isdown(self):
212097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return True if pen is down, False if it's up.
212197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
212297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
212397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
212497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
212597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.penup()
212697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.isdown()
212797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        False
212897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pendown()
212997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.isdown()
213097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        True
213197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
213297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._drawing
213397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
213497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def speed(self, speed=None):
213597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return or set the turtle's speed.
213697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
213797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
213897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speed -- an integer in the range 0..10 or a speedstring (see below)
213997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
214097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set the turtle's speed to an integer value in the range 0 .. 10.
214197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If no argument is given: return current speed.
214297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
214397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If input is a number greater than 10 or smaller than 0.5,
214497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speed is set to 0.
214597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Speedstrings  are mapped to speedvalues in the following way:
214697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            'fastest' :  0
214797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            'fast'    :  10
214897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            'normal'  :  6
214997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            'slow'    :  3
215097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            'slowest' :  1
215197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speeds from 1 to 10 enforce increasingly faster animation of
215297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        line drawing and turtle turning.
215397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
215497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Attention:
215597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speed = 0 : *no* animation takes place. forward/back makes turtle jump
215697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        and likewise left/right make the turtle turn instantly.
215797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
215897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
215997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.speed(3)
216097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
216197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speeds = {'fastest':0, 'fast':10, 'normal':6, 'slow':3, 'slowest':1 }
216297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if speed is None:
216397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._speed
216497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if speed in speeds:
216597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            speed = speeds[speed]
216697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif 0.5 < speed < 10.5:
216797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            speed = int(round(speed))
216897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
216997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            speed = 0
217097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(speed=speed)
217197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
217297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def color(self, *args):
217397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return or set the pencolor and fillcolor.
217497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
217597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
217697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Several input formats are allowed.
217797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        They use 0, 1, 2, or 3 arguments as follows:
217897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
217997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color()
218097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            Return the current pencolor and the current fillcolor
218197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            as a pair of color specification strings as are returned
218297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            by pencolor and fillcolor.
218397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color(colorstring), color((r,g,b)), color(r,g,b)
218497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            inputs as in pencolor, set both, fillcolor and pencolor,
218597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            to the given value.
218697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color(colorstring1, colorstring2),
218797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color((r1,g1,b1), (r2,g2,b2))
218897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            equivalent to pencolor(colorstring1) and fillcolor(colorstring2)
218997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            and analogously, if the other input format is used.
219097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
219197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If turtleshape is a polygon, outline and interior of that polygon
219297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        is drawn with the newly set colors.
219397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        For mor info see: pencolor, fillcolor
219497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
219597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
219697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.color('red', 'green')
219797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.color()
219897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ('red', 'green')
219997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> colormode(255)
220097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> color((40, 80, 120), (160, 200, 240))
220197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> color()
220297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ('#285078', '#a0c8f0')
220397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
220497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if args:
220597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            l = len(args)
220697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if l == 1:
220797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                pcolor = fcolor = args[0]
220897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            elif l == 2:
220997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                pcolor, fcolor = args
221097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            elif l == 3:
221197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                pcolor = fcolor = args
221297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pcolor = self._colorstr(pcolor)
221397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            fcolor = self._colorstr(fcolor)
221497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.pen(pencolor=pcolor, fillcolor=fcolor)
221597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
221697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._color(self._pencolor), self._color(self._fillcolor)
221797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
221897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def pencolor(self, *args):
221997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return or set the pencolor.
222097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
222197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
222297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Four input formats are allowed:
222397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - pencolor()
222497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            Return the current pencolor as color specification string,
222597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            possibly in hex-number format (see example).
222697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            May be used as input to another color/pencolor/fillcolor call.
222797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - pencolor(colorstring)
222897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            s is a Tk color specification string, such as "red" or "yellow"
222997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - pencolor((r, g, b))
223097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            *a tuple* of r, g, and b, which represent, an RGB color,
223197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            and each of r, g, and b are in the range 0..colormode,
223297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            where colormode is either 1.0 or 255
223397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - pencolor(r, g, b)
223497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            r, g, and b represent an RGB color, and each of r, g, and b
223597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            are in the range 0..colormode
223697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
223797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If turtleshape is a polygon, the outline of that polygon is drawn
223897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        with the newly set pencolor.
223997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
224097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
224197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pencolor('brown')
224297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> tup = (0.2, 0.8, 0.55)
224397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pencolor(tup)
224497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pencolor()
224597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        '#33cc8c'
224697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
224797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if args:
224897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            color = self._colorstr(args)
224997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if color == self._pencolor:
225097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                return
225197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.pen(pencolor=color)
225297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
225397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._color(self._pencolor)
225497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
225597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def fillcolor(self, *args):
225697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return or set the fillcolor.
225797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
225897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
225997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Four input formats are allowed:
226097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - fillcolor()
226197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            Return the current fillcolor as color specification string,
226297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            possibly in hex-number format (see example).
226397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            May be used as input to another color/pencolor/fillcolor call.
226497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - fillcolor(colorstring)
226597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            s is a Tk color specification string, such as "red" or "yellow"
226697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - fillcolor((r, g, b))
226797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            *a tuple* of r, g, and b, which represent, an RGB color,
226897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            and each of r, g, and b are in the range 0..colormode,
226997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            where colormode is either 1.0 or 255
227097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - fillcolor(r, g, b)
227197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            r, g, and b represent an RGB color, and each of r, g, and b
227297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            are in the range 0..colormode
227397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
227497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If turtleshape is a polygon, the interior of that polygon is drawn
227597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        with the newly set fillcolor.
227697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
227797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
227897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fillcolor('violet')
227997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> col = turtle.pencolor()
228097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fillcolor(col)
228197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fillcolor(0, .5, 0)
228297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
228397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if args:
228497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            color = self._colorstr(args)
228597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if color == self._fillcolor:
228697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                return
228797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.pen(fillcolor=color)
228897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
228997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._color(self._fillcolor)
229097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
229197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def showturtle(self):
229297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Makes the turtle visible.
229397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
229497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: showturtle | st
229597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
229697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
229797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
229897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
229997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.hideturtle()
230097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.showturtle()
230197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
230297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(shown=True)
230397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
230497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def hideturtle(self):
230597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Makes the turtle invisible.
230697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
230797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: hideturtle | ht
230897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
230997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
231097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
231197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        It's a good idea to do this while you're in the
231297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        middle of a complicated drawing, because hiding
231397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        the turtle speeds up the drawing observably.
231497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
231597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
231697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.hideturtle()
2317477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
231897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(shown=False)
2319b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
232097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def isvisible(self):
232197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return True if the Turtle is shown, False if it's hidden.
2322477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
232397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
232497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
232597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
232697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.hideturtle()
232797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> print turtle.isvisible():
232897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        False
2329477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
233097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._shown
233197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
233297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def pen(self, pen=None, **pendict):
233397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return or set the pen's attributes.
233497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
233597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
233697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pen -- a dictionary with some or all of the below listed keys.
233797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            **pendict -- one or more keyword-arguments with the below
233897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                         listed keys as keywords.
233997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
234097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Return or set the pen's attributes in a 'pen-dictionary'
234197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        with the following key/value pairs:
234297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "shown"      :   True/False
234397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "pendown"    :   True/False
234497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "pencolor"   :   color-string or color-tuple
234597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "fillcolor"  :   color-string or color-tuple
234697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "pensize"    :   positive number
234797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "speed"      :   number in range 0..10
234897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "resizemode" :   "auto" or "user" or "noresize"
234997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "stretchfactor": (positive number, positive number)
2350eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl           "shearfactor":   number
235197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "outline"    :   positive number
235297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "tilt"       :   number
235397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
2354f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        This dictionary can be used as argument for a subsequent
235597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pen()-call to restore the former pen-state. Moreover one
235697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        or more of these attributes can be provided as keyword-arguments.
235797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        This can be used to set several pen attributes in one statement.
235897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
235997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
236097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Turtle instance named turtle):
236197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10)
236297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pen()
236397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
236497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'pencolor': 'red', 'pendown': True, 'fillcolor': 'black',
2365eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'stretchfactor': (1,1), 'speed': 3, 'shearfactor': 0.0}
236697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> penstate=turtle.pen()
236797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.color("yellow","")
236897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.penup()
236997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pen()
237097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
237197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'pencolor': 'yellow', 'pendown': False, 'fillcolor': '',
2372eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'stretchfactor': (1,1), 'speed': 3, 'shearfactor': 0.0}
237397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> p.pen(penstate, fillcolor="green")
237497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> p.pen()
237597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
237697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'pencolor': 'red', 'pendown': True, 'fillcolor': 'green',
2377eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'stretchfactor': (1,1), 'speed': 3, 'shearfactor': 0.0}
237897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
237997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        _pd =  {"shown"         : self._shown,
238097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "pendown"       : self._drawing,
238197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "pencolor"      : self._pencolor,
238297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "fillcolor"     : self._fillcolor,
238397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "pensize"       : self._pensize,
238497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "speed"         : self._speed,
238597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "resizemode"    : self._resizemode,
238697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "stretchfactor" : self._stretchfactor,
2387eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                "shearfactor"   : self._shearfactor,
238897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "outline"       : self._outlinewidth,
238997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "tilt"          : self._tilt
239097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis               }
239197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
239297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not (pen or pendict):
239397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return _pd
239497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
239597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(pen, dict):
239697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            p = pen
239797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
239897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            p = {}
239997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        p.update(pendict)
240097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
240197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        _p_buf = {}
240297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for key in p:
240397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            _p_buf[key] = _pd[key]
240497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
240597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
240697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.push(("pen", _p_buf))
240797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
240897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        newLine = False
240997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "pendown" in p:
241097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._drawing != p["pendown"]:
241197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                newLine = True
241297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "pencolor" in p:
241397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if isinstance(p["pencolor"], tuple):
241497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                p["pencolor"] = self._colorstr((p["pencolor"],))
241597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._pencolor != p["pencolor"]:
241697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                newLine = True
241797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "pensize" in p:
241897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._pensize != p["pensize"]:
241997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                newLine = True
242097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if newLine:
242197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._newLine()
242297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "pendown" in p:
242397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._drawing = p["pendown"]
242497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "pencolor" in p:
242597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._pencolor = p["pencolor"]
242697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "pensize" in p:
242797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._pensize = p["pensize"]
242897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "fillcolor" in p:
242997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if isinstance(p["fillcolor"], tuple):
243097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                p["fillcolor"] = self._colorstr((p["fillcolor"],))
243197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._fillcolor = p["fillcolor"]
243297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "speed" in p:
243397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._speed = p["speed"]
243497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "resizemode" in p:
243597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._resizemode = p["resizemode"]
243697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "stretchfactor" in p:
243797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            sf = p["stretchfactor"]
243897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if isinstance(sf, (int, float)):
243997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                sf = (sf, sf)
244097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._stretchfactor = sf
2441eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if "shearfactor" in p:
2442eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            self._shearfactor = p["shearfactor"]
244397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "outline" in p:
244497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._outlinewidth = p["outline"]
244597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "shown" in p:
244697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._shown = p["shown"]
244797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "tilt" in p:
244897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._tilt = p["tilt"]
2449eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if "stretchfactor" in p or "tilt" in p or "shearfactor" in p:
2450eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            scx, scy = self._stretchfactor
2451eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            shf = self._shearfactor
2452eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            sa, ca = math.sin(self._tilt), math.cos(self._tilt)
2453eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            self._shapetrafo = ( scx*ca, scy*(shf*ca + sa),
2454eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                                -scx*sa, scy*(ca - shf*sa))
245597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
245697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
245797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis## three dummy methods to be implemented by child class:
245897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
245997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _newLine(self, usePos = True):
246097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """dummy method - to be overwritten by child class"""
246197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _update(self, count=True, forced=False):
246297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """dummy method - to be overwritten by child class"""
246397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _color(self, args):
246497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """dummy method - to be overwritten by child class"""
246597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _colorstr(self, args):
246697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """dummy method - to be overwritten by child class"""
246797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
246897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    width = pensize
246997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    up = penup
247097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    pu = penup
247197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    pd = pendown
247297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    down = pendown
247397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    st = showturtle
247497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    ht = hideturtle
247597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
247697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
247797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass _TurtleImage(object):
247897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Helper class: Datatype to store Turtle attributes
247997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
248097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
248197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, screen, shapeIndex):
248297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screen = screen
248397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._type = None
248497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._setshape(shapeIndex)
248597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
248697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _setshape(self, shapeIndex):
2487eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        screen = self.screen
248897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.shapeIndex = shapeIndex
248997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._type == "polygon" == screen._shapes[shapeIndex]._type:
249097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
249197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._type == "image" == screen._shapes[shapeIndex]._type:
249297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
249397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._type in ["image", "polygon"]:
249497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            screen._delete(self._item)
249597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif self._type == "compound":
249697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for item in self._item:
249797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._delete(item)
249897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._type = screen._shapes[shapeIndex]._type
249997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._type == "polygon":
250097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._item = screen._createpoly()
250197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif self._type == "image":
250297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._item = screen._createimage(screen._shapes["blank"]._data)
250397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif self._type == "compound":
250497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._item = [screen._createpoly() for item in
250597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                          screen._shapes[shapeIndex]._data]
250697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
250797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
250897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass RawTurtle(TPen, TNavigator):
250997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Animation part of the RawTurtle.
251097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Puts RawTurtle upon a TurtleScreen and provides tools for
2511f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson    its animation.
251297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
251397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    screens = []
251497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
251597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, canvas=None,
251697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 shape=_CFG["shape"],
251797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 undobuffersize=_CFG["undobuffersize"],
251897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 visible=_CFG["visible"]):
2519601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        if isinstance(canvas, _Screen):
252097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen = canvas
252197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif isinstance(canvas, TurtleScreen):
252297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if canvas not in RawTurtle.screens:
252397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                RawTurtle.screens.append(canvas)
252497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen = canvas
252597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif isinstance(canvas, (ScrolledCanvas, Canvas)):
252697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for screen in RawTurtle.screens:
252797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if screen.cv == canvas:
252897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    self.screen = screen
252997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    break
253097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
253197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.screen = TurtleScreen(canvas)
253297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                RawTurtle.screens.append(self.screen)
253397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
253497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("bad cavas argument %s" % canvas)
253597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
253697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
253797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TNavigator.__init__(self, screen.mode())
253897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TPen.__init__(self)
253997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen._turtles.append(self)
254097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.drawingLineItem = screen._createline()
254197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.turtle = _TurtleImage(screen, shape)
254297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._poly = None
254397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._creatingPoly = False
254497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._fillitem = self._fillpath = None
254597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._shown = visible
254697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._hidden_from_screen = False
254797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.currentLineItem = screen._createline()
254897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.currentLine = [self._position]
254997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.items = [self.currentLineItem]
255097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.stampItems = []
255197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._undobuffersize = undobuffersize
255297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.undobuffer = Tbuffer(undobuffersize)
255397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
2554b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
2555b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum    def reset(self):
2556f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        """Delete the turtle's drawings and restore its default values.
2557477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
255897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
255997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis,
256097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Delete the turtle's drawings from the screen, re-center the turtle
256197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        and set variables to the default values.
256297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
256397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
2564477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.position()
256597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00,-22.00)
2566477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.heading()
2567477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        100.0
2568477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.reset()
2569477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.position()
257097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00,0.00)
2571477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.heading()
2572477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        0.0
2573477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
257497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TNavigator.reset(self)
257597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TPen._reset(self)
257697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._clear()
257797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._drawturtle()
257897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
2579b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
258097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def setundobuffer(self, size):
258197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set or disable undobuffer.
2582477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
258397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
258497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        size -- an integer or None
25853c7a25a4d9ea07f2aa8e4b70fecd84e33de82c2eGuido van Rossum
258697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If size is an integer an empty undobuffer of given size is installed.
258797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Size gives the maximum number of turtle-actions that can be undone
258897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        by the undo() function.
258997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If size is None, no undobuffer is present.
2590477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
259197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
259297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.setundobuffer(42)
2593477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
259497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if size is None:
259597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer = None
259697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
259797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer = Tbuffer(size)
2598b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
259997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def undobufferentries(self):
260097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return count of entries in the undobuffer.
2601477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
260297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
260397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
260497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
260597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> while undobufferentries():
260697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                undo()
2607477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
260897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer is None:
260997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return 0
261097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.undobuffer.nr_of_items()
261197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
261297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _clear(self):
261397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Delete all of pen's drawings"""
261497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._fillitem = self._fillpath = None
261597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for item in self.items:
261697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen._delete(item)
261797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.currentLineItem = self.screen._createline()
261897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.currentLine = []
261997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._drawing:
262097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.currentLine.append(self._position)
262197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.items = [self.currentLineItem]
262297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.clearstamps()
262397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.setundobuffer(self._undobuffersize)
2624b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
2625477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
262697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def clear(self):
262797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Delete the turtle's drawings from the screen. Do not move turtle.
2628477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
262997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
2630b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
263197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Delete the turtle's drawings from the screen. Do not move turtle.
263297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        State and position of the turtle as well as drawings of other
263397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtles are not affected.
2634477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
263597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Turtle instance named turtle):
263697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.clear()
263797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
263897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._clear()
263997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
2640477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
264197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _update_data(self):
264297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screen._incrementudc()
264397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.screen._updatecounter != 0:
264497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
264597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if len(self.currentLine)>1:
264697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen._drawline(self.currentLineItem, self.currentLine,
264797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                  self._pencolor, self._pensize)
264897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
264997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _update(self):
265097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Perform a Turtle-data update.
2651477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
265297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
265397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if screen._tracing == 0:
265497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
265597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif screen._tracing == 1:
265697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._update_data()
265797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._drawturtle()
265897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            screen._update()                  # TurtleScreenBase
265997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            screen._delay(screen._delayvalue) # TurtleScreenBase
266097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
266197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._update_data()
266297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if screen._updatecounter == 0:
266397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                for t in screen.turtles():
266497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    t._drawturtle()
266597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._update()
266697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
266797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _tracer(self, flag=None, delay=None):
266897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Turns turtle animation on/off and set delay for update drawings.
266997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
267097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional arguments:
267197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        n -- nonnegative  integer
267297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        delay -- nonnegative  integer
267397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
267497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If n is given, only each n-th regular screen update is really performed.
267597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (Can be used to accelerate the drawing of complex graphics.)
267697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Second arguments sets delay value (see RawTurtle.delay())
267797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
267897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
267997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.tracer(8, 25)
268097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> dist = 2
268197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> for i in range(200):
268297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                turtle.fd(dist)
268397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                turtle.rt(90)
268497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                dist += 2
268597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
268697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.screen.tracer(flag, delay)
2687b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
268897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _color(self, args):
268997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.screen._color(args)
2690477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
269197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _colorstr(self, args):
269297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.screen._colorstr(args)
2693477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
269497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _cc(self, args):
269597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Convert colortriples to hexstrings.
2696477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
269797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(args, str):
269897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return args
269997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        try:
270097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            r, g, b = args
270197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        except:
270297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("bad color arguments: %s" % str(args))
270397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.screen._colormode == 1.0:
270497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            r, g, b = [round(255.0*x) for x in (r, g, b)]
270597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)):
270697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("bad color sequence: %s" % str(args))
270797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return "#%02x%02x%02x" % (r, g, b)
2708b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
270997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def clone(self):
271097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Create and return a clone of the turtle.
2711477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
271297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
2713b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
271497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Create and return a clone of the turtle with same position, heading
271597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        and turtle properties.
2716477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
271797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named mick):
271897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        mick = Turtle()
271997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        joe = mick.clone()
272097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
272197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
272297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._newLine(self._drawing)
272397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
272497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle = self.turtle
272597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screen = None
272697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.turtle = None  # too make self deepcopy-able
272797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
272897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        q = deepcopy(self)
272997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
273097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screen = screen
273197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.turtle = turtle
273297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
273397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        q.screen = screen
273497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        q.turtle = _TurtleImage(screen, self.turtle.shapeIndex)
273597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
273697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen._turtles.append(q)
273797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ttype = screen._shapes[self.turtle.shapeIndex]._type
273897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if ttype == "polygon":
273997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            q.turtle._item = screen._createpoly()
274097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif ttype == "image":
274197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            q.turtle._item = screen._createimage(screen._shapes["blank"]._data)
274297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif ttype == "compound":
274397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            q.turtle._item = [screen._createpoly() for item in
274497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              screen._shapes[self.turtle.shapeIndex]._data]
274597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        q.currentLineItem = screen._createline()
274697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        q._update()
274797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return q
274897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
274997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def shape(self, name=None):
275097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set turtle shape to shape with given name / return current shapename.
275197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
275297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
275397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        name -- a string, which is a valid shapename
275497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
275597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set turtle shape to shape with given name or, if name is not given,
275697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return name of current shape.
275797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Shape with name must exist in the TurtleScreen's shape dictionary.
275897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Initially there are the following polygon shapes:
275997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'arrow', 'turtle', 'circle', 'square', 'triangle', 'classic'.
276097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        To learn about how to deal with shapes see Screen-method register_shape.
276197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
276297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
276397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shape()
276497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'arrow'
276597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shape("turtle")
276697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shape()
276797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'turtle'
276897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
276997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if name is None:
277097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self.turtle.shapeIndex
277197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not name in self.screen.getshapes():
277297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("There is no shape named %s" % name)
277397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.turtle._setshape(name)
277497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
277597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
277697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def shapesize(self, stretch_wid=None, stretch_len=None, outline=None):
277797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set/return turtle's stretchfactors/outline. Set resizemode to "user".
277897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
277997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optinonal arguments:
278097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           stretch_wid : positive number
278197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           stretch_len : positive number
278297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           outline  : positive number
278397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
278497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Return or set the pen's attributes x/y-stretchfactors and/or outline.
278597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set resizemode to "user".
278697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If and only if resizemode is set to "user", the turtle will be displayed
278797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        stretched according to its stretchfactors:
278897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        stretch_wid is stretchfactor perpendicular to orientation
278997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        stretch_len is stretchfactor in direction of turtles orientation.
279097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        outline determines the width of the shapes's outline.
279197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
279297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Turtle instance named turtle):
279397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.resizemode("user")
279497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shapesize(5, 5, 12)
279597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shapesize(outline=8)
279697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
2797fd1b0930ce6a84096d30c03a70cd9e0ee4a3178fFlorent Xicluna        if stretch_wid is stretch_len is outline is None:
279897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stretch_wid, stretch_len = self._stretchfactor
279997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return stretch_wid, stretch_len, self._outlinewidth
2800eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if stretch_wid == 0 or stretch_len == 0:
2801eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            raise TurtleGraphicsError("stretch_wid/stretch_len must not be zero")
280297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if stretch_wid is not None:
280397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if stretch_len is None:
280497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                stretchfactor = stretch_wid, stretch_wid
280597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
280697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                stretchfactor = stretch_wid, stretch_len
280797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif stretch_len is not None:
280897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stretchfactor = self._stretchfactor[0], stretch_len
280997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
281097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stretchfactor = self._stretchfactor
281197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if outline is None:
281297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            outline = self._outlinewidth
281397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(resizemode="user",
281497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 stretchfactor=stretchfactor, outline=outline)
281597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
2816eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def shearfactor(self, shear=None):
2817eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Set or return the current shearfactor.
2818eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2819eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Optional argument: shear -- number, tangent of the shear angle
2820eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2821eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Shear the turtleshape according to the given shearfactor shear,
2822eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        which is the tangent of the shear angle. DO NOT change the
2823eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        turtle's heading (direction of movement).
2824eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        If shear is not given: return the current shearfactor, i. e. the
2825eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        tangent of the shear angle, by which lines parallel to the
2826eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        heading of the turtle are sheared.
2827eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2828eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Examples (for a Turtle instance named turtle):
2829eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shape("circle")
2830eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shapesize(5,2)
2831eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shearfactor(0.5)
2832eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shearfactor()
2833eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> 0.5
2834eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
2835eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if shear is None:
2836eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            return self._shearfactor
2837eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self.pen(resizemode="user", shearfactor=shear)
2838eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
283997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def settiltangle(self, angle):
284097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Rotate the turtleshape to point in the specified direction
284197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
2842eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Argument: angle -- number
284397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
284497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Rotate the turtleshape to point in the direction specified by angle,
284597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        regardless of its current tilt-angle. DO NOT change the turtle's
284697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        heading (direction of movement).
284797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
284897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
284997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Turtle instance named turtle):
285097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shape("circle")
285197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shapesize(5,2)
285297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.settiltangle(45)
285397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> stamp()
285497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fd(50)
285597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.settiltangle(-45)
285697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> stamp()
285797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fd(50)
2858477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
285997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tilt = -angle * self._degreesPerAU * self._angleOrient
286097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tilt = (tilt * math.pi / 180.0) % (2*math.pi)
286197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(resizemode="user", tilt=tilt)
2862b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
2863eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def tiltangle(self, angle=None):
2864eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Set or return the current tilt-angle.
2865477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
2866eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Optional argument: angle -- number
2867eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2868eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Rotate the turtleshape to point in the direction specified by angle,
2869eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        regardless of its current tilt-angle. DO NOT change the turtle's
2870eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        heading (direction of movement).
2871eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        If angle is not given: return the current tilt-angle, i. e. the angle
2872eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        between the orientation of the turtleshape and the heading of the
2873eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        turtle (its direction of movement).
2874b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
2875eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Deprecated since Python 3.1
2876477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
287797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Turtle instance named turtle):
287897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shape("circle")
287997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shapesize(5,2)
288097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.tilt(45)
288197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.tiltangle()
288297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>>
288397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
2884eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if angle is None:
2885eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            tilt = -self._tilt * (180.0/math.pi) * self._angleOrient
2886eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            return (tilt / self._degreesPerAU) % self._fullcircle
2887eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        else:
2888eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            self.settiltangle(angle)
2889477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
289097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def tilt(self, angle):
289197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Rotate the turtleshape by angle.
2892477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
289397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
289497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle - a number
2895477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
289697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Rotate the turtleshape by angle from its current tilt-angle,
289797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        but do NOT change the turtle's heading (direction of movement).
2898477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
289997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Turtle instance named turtle):
290097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shape("circle")
290197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shapesize(5,2)
290297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.tilt(30)
290397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fd(50)
290497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.tilt(30)
290597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fd(50)
290697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
290797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.settiltangle(angle + self.tiltangle())
2908477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
2909eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def shapetransform(self, t11=None, t12=None, t21=None, t22=None):
2910eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Set or return the current transformation matrix of the turtle shape.
2911eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2912eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Optional arguments: t11, t12, t21, t22 -- numbers.
2913eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2914eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        If none of the matrix elements are given, return the transformation
2915eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        matrix.
2916eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Otherwise set the given elements and transform the turtleshape
2917eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        according to the matrix consisting of first row t11, t12 and
2918eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        second row t21, 22.
2919eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Modify stretchfactor, shearfactor and tiltangle according to the
2920eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        given matrix.
2921eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2922eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Examples (for a Turtle instance named turtle):
2923eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shape("square")
2924eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shapesize(4,2)
2925eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shearfactor(-0.5)
2926eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shapetransform()
2927eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> (4.0, -1.0, -0.0, 2.0)
2928eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
2929eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if t11 is t12 is t21 is t22 is None:
2930eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            return self._shapetrafo
2931eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        m11, m12, m21, m22 = self._shapetrafo
2932eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if t11 is not None: m11 = t11
2933eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if t12 is not None: m12 = t12
2934eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if t21 is not None: m21 = t21
2935eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if t22 is not None: m22 = t22
2936eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if t11 * t22 - t12 * t21 == 0:
2937eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            raise TurtleGraphicsError("Bad shape transform matrix: must not be singular")
2938eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._shapetrafo = (m11, m12, m21, m22)
2939eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        alfa = math.atan2(-m21, m11) % (2 * math.pi)
2940eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        sa, ca = math.sin(alfa), math.cos(alfa)
2941eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        a11, a12, a21, a22 = (ca*m11 - sa*m21, ca*m12 - sa*m22,
2942eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                              sa*m11 + ca*m21, sa*m12 + ca*m22)
2943eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._stretchfactor = a11, a22
2944eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._shearfactor = a12/a22
2945eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._tilt = alfa
2946eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._update()
2947eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2948eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
294997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _polytrafo(self, poly):
295097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Computes transformed polygon shapes from a shape
295197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        according to current position and heading.
295297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
295397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
295497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        p0, p1 = self._position
295597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        e0, e1 = self._orient
295697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        e = Vec2D(e0, e1 * screen.yscale / screen.xscale)
295797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        e0, e1 = (1.0 / abs(e)) * e
295897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return [(p0+(e1*x+e0*y)/screen.xscale, p1+(-e0*x+e1*y)/screen.yscale)
295997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                           for (x, y) in poly]
296097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
2961eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def get_shapepoly(self):
2962eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Return the current shape polygon as tuple of coordinate pairs.
2963eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2964eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        No argument.
2965eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2966eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Examples (for a Turtle instance named turtle):
2967eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shape("square")
2968eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shapetransform(4, -1, 0, 2)
2969eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.get_shapepoly()
2970eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        ((50, -20), (30, 20), (-50, 20), (-30, -20))
2971eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2972eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
2973eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        shape = self.screen._shapes[self.turtle.shapeIndex]
2974eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if shape._type == "polygon":
2975eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            return self._getshapepoly(shape._data, shape._type == "compound")
2976eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        # else return None
2977eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2978eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def _getshapepoly(self, polygon, compound=False):
2979eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Calculate transformed shape polygon according to resizemode
2980eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        and shapetransform.
2981eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
2982eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if self._resizemode == "user" or compound:
2983eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            t11, t12, t21, t22 = self._shapetrafo
2984eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        elif self._resizemode == "auto":
2985eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            l = max(1, self._pensize/5.0)
2986eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            t11, t12, t21, t22 = l, 0, 0, l
2987eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        elif self._resizemode == "noresize":
2988eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            return polygon
2989eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        return tuple([(t11*x + t12*y, t21*x + t22*y) for (x, y) in polygon])
2990eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
299197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _drawturtle(self):
299297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Manages the correct rendering of the turtle with respect to
2993934896dc0977ea25dc37c13117525f2394625ceeMark Dickinson        its shape, resizemode, stretch and tilt etc."""
299497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
299597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        shape = screen._shapes[self.turtle.shapeIndex]
299697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ttype = shape._type
299797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        titem = self.turtle._item
299897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._shown and screen._updatecounter == 0 and screen._tracing > 0:
299997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._hidden_from_screen = False
300097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            tshape = shape._data
300197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if ttype == "polygon":
3002eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                if self._resizemode == "noresize": w = 1
3003eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                elif self._resizemode == "auto": w = self._pensize
3004eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                else: w =self._outlinewidth
3005eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                shape = self._polytrafo(self._getshapepoly(tshape))
300697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fc, oc = self._fillcolor, self._pencolor
300797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._drawpoly(titem, shape, fill=fc, outline=oc,
300897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                      width=w, top=True)
300997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            elif ttype == "image":
301097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._drawimage(titem, self._position, tshape)
301197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            elif ttype == "compound":
301297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                for item, (poly, fc, oc) in zip(titem, tshape):
3013eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                    poly = self._polytrafo(self._getshapepoly(poly, True))
301497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    screen._drawpoly(item, poly, fill=self._cc(fc),
3015eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                                     outline=self._cc(oc), width=self._outlinewidth, top=True)
301697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
301797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._hidden_from_screen:
3018b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum                return
301997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if ttype == "polygon":
302097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._drawpoly(titem, ((0, 0), (0, 0), (0, 0)), "", "")
302197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            elif ttype == "image":
302297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._drawimage(titem, self._position,
302397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                          screen._shapes["blank"]._data)
302497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            elif ttype == "compound":
302597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                for item in titem:
302697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    screen._drawpoly(item, ((0, 0), (0, 0), (0, 0)), "", "")
302797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._hidden_from_screen = True
302897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
302997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis##############################  stamp stuff  ###############################
303097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
303197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def stamp(self):
3032f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        """Stamp a copy of the turtleshape onto the canvas and return its id.
303397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
303497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
303597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
303697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Stamp a copy of the turtle shape onto the canvas at the current
303797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle position. Return a stamp_id for that stamp, which can be
303897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        used to delete it by calling clearstamp(stamp_id).
303997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
304097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
304197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.color("blue")
304297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.stamp()
304397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        13
304497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fd(50)
304597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
304697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
304797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        shape = screen._shapes[self.turtle.shapeIndex]
304897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ttype = shape._type
304997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tshape = shape._data
305097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if ttype == "polygon":
305197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stitem = screen._createpoly()
3052eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            if self._resizemode == "noresize": w = 1
3053eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            elif self._resizemode == "auto": w = self._pensize
3054eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            else: w =self._outlinewidth
3055eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            shape = self._polytrafo(self._getshapepoly(tshape))
305697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            fc, oc = self._fillcolor, self._pencolor
305797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            screen._drawpoly(stitem, shape, fill=fc, outline=oc,
305897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                  width=w, top=True)
305997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif ttype == "image":
306097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stitem = screen._createimage("")
306197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            screen._drawimage(stitem, self._position, tshape)
306297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif ttype == "compound":
306397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stitem = []
306497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for element in tshape:
306597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                item = screen._createpoly()
306697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                stitem.append(item)
306797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stitem = tuple(stitem)
306897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for item, (poly, fc, oc) in zip(stitem, tshape):
3069eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                poly = self._polytrafo(self._getshapepoly(poly, True))
307097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._drawpoly(item, poly, fill=self._cc(fc),
3071eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                                 outline=self._cc(oc), width=self._outlinewidth, top=True)
307297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.stampItems.append(stitem)
307397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.undobuffer.push(("stamp", stitem))
307497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return stitem
307597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
307697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _clearstamp(self, stampid):
307797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """does the work for clearstamp() and clearstamps()
307897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
307997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if stampid in self.stampItems:
308097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if isinstance(stampid, tuple):
308197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                for subitem in stampid:
308297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    self.screen._delete(subitem)
308397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
308497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.screen._delete(stampid)
308597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.stampItems.remove(stampid)
308697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # Delete stampitem from undobuffer if necessary
308797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # if clearstamp is called directly.
308897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        item = ("stamp", stampid)
308997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        buf = self.undobuffer
309097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if item not in buf.buffer:
309197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
309297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        index = buf.buffer.index(item)
309397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        buf.buffer.remove(item)
309497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if index <= buf.ptr:
309597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            buf.ptr = (buf.ptr - 1) % buf.bufsize
309697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        buf.buffer.insert((buf.ptr+1)%buf.bufsize, [None])
309797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
309897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def clearstamp(self, stampid):
309997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Delete stamp with given stampid
310097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
310197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
310297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        stampid - an integer, must be return value of previous stamp() call.
310397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
310497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
310597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.color("blue")
310697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> astamp = turtle.stamp()
310797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fd(50)
310897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.clearstamp(astamp)
310997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
311097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._clearstamp(stampid)
311197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
311297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
311397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def clearstamps(self, n=None):
311497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Delete all or first/last n of turtle's stamps.
311597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
311697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
311797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        n -- an integer
311897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
311997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If n is None, delete all of pen's stamps,
312097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else if n > 0 delete first n stamps
312197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else if n < 0 delete last n stamps.
312297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
312397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
312497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> for i in range(8):
312597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                turtle.stamp(); turtle.fd(30)
312697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ...
312797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.clearstamps(2)
312897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.clearstamps(-2)
312997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.clearstamps()
313097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
313197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if n is None:
313297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            toDelete = self.stampItems[:]
313397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif n >= 0:
313497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            toDelete = self.stampItems[:n]
3135b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum        else:
313697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            toDelete = self.stampItems[n:]
313797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for item in toDelete:
313897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._clearstamp(item)
313997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
314097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
314197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _goto(self, end):
314297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Move the pen to the point end, thereby drawing a line
314397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if pen is down. All other methodes for turtle movement depend
314497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        on this one.
314597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
314697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ## Version mit undo-stuff
314797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        go_modes = ( self._drawing,
314897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                     self._pencolor,
314997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                     self._pensize,
315097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                     isinstance(self._fillpath, list))
315197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
315297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        undo_entry = ("go", self._position, end, go_modes,
315397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                      (self.currentLineItem,
315497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                      self.currentLine[:],
315597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                      screen._pointlist(self.currentLineItem),
315697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                      self.items[:])
315797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                      )
315897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
315997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.push(undo_entry)
316097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        start = self._position
316197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._speed and screen._tracing == 1:
316297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            diff = (end-start)
316397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2
316497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
316597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            delta = diff * (1.0/nhops)
316697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for n in range(1, nhops):
316797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if n == 1:
316897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    top = True
316997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                else:
317097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    top = False
317197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._position = start + delta * n
317297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if self._drawing:
317397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    screen._drawline(self.drawingLineItem,
317497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                     (start, self._position),
317597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                     self._pencolor, self._pensize, top)
317697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._update()
317797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._drawing:
317897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
317997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                               fill="", width=self._pensize)
318097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # Turtle now at end,
318197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._drawing: # now update currentLine
318297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.currentLine.append(end)
318397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(self._fillpath, list):
318497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._fillpath.append(end)
318597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ######    vererbung!!!!!!!!!!!!!!!!!!!!!!
318697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._position = end
318797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._creatingPoly:
318897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._poly.append(end)
318997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if len(self.currentLine) > 42: # 42! answer to the ultimate question
319097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                       # of life, the universe and everything
319197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._newLine()
319297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update() #count=True)
319397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
319497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _undogoto(self, entry):
319597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Reverse a _goto. Used for undo()
319697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
319797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        old, new, go_modes, coodata = entry
319897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        drawing, pc, ps, filling = go_modes
319997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cLI, cL, pl, items = coodata
320097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
320197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if abs(self._position - new) > 0.5:
320297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            print ("undogoto: HALLO-DA-STIMMT-WAS-NICHT!")
320397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # restore former situation
320497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.currentLineItem = cLI
320597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.currentLine = cL
320697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
320797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if pl == [(0, 0), (0, 0)]:
320897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            usepc = ""
320997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
321097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            usepc = pc
321197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen._drawline(cLI, pl, fill=usepc, width=ps)
321297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
321397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        todelete = [i for i in self.items if (i not in items) and
321497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                       (screen._type(i) == "line")]
321597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for i in todelete:
321697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            screen._delete(i)
321797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.items.remove(i)
321897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
321997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        start = old
322097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._speed and screen._tracing == 1:
322197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            diff = old - new
322297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2
322397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
322497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            delta = diff * (1.0/nhops)
322597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for n in range(1, nhops):
322697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if n == 1:
322797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    top = True
322897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                else:
322997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    top = False
323097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._position = new + delta * n
323197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if drawing:
323297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    screen._drawline(self.drawingLineItem,
323397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                     (start, self._position),
323497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                     pc, ps, top)
323597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._update()
323697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if drawing:
323797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
323897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                               fill="", width=ps)
323997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # Turtle now at position old,
324097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._position = old
324197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ##  if undo is done during crating a polygon, the last vertex
324297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ##  will be deleted. if the polygon is entirel deleted,
324397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ##  creatigPoly will be set to False.
324497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ##  Polygons created before the last one will not be affected by undo()
324597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._creatingPoly:
324697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if len(self._poly) > 0:
324797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._poly.pop()
324897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._poly == []:
324997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._creatingPoly = False
325097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._poly = None
325197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if filling:
325297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._fillpath == []:
325397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._fillpath = None
325497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                print("Unwahrscheinlich in _undogoto!")
325597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            elif self._fillpath is not None:
325697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._fillpath.pop()
325797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update() #count=True)
325897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
325997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _rotate(self, angle):
326097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Turns pen clockwise by angle.
326197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
326297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
326397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.push(("rot", angle, self._degreesPerAU))
326497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle *= self._degreesPerAU
326597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        neworient = self._orient.rotate(angle)
326697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tracing = self.screen._tracing
326797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if tracing == 1 and self._speed > 0:
326897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            anglevel = 3.0 * self._speed
326997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            steps = 1 + int(abs(angle)/anglevel)
327097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            delta = 1.0*angle/steps
327197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for _ in range(steps):
327297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._orient = self._orient.rotate(delta)
327397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._update()
327497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._orient = neworient
327597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
327697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
327797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _newLine(self, usePos=True):
327897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Closes current line item and starts a new one.
327997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           Remark: if current line became too long, animation
328097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           performance (via _drawline) slowed down considerably.
328197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
328297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if len(self.currentLine) > 1:
328397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen._drawline(self.currentLineItem, self.currentLine,
328497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                      self._pencolor, self._pensize)
328597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.currentLineItem = self.screen._createline()
328697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.items.append(self.currentLineItem)
328797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
328897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen._drawline(self.currentLineItem, top=True)
328997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.currentLine = []
329097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if usePos:
329197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.currentLine = [self._position]
3292477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
329397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def filling(self):
329497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return fillstate (True if filling, False else).
3295b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
329697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
3297477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
329897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
329997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.begin_fill()
330097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> if turtle.filling():
330197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                turtle.pensize(5)
330297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
330397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                turtle.pensize(3)
330497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
330597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return isinstance(self._fillpath, list)
330697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
3307477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    def begin_fill(self):
330897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Called just before drawing a shape to be filled.
3309477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
331097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
331197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
331297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
331397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.color("black", "red")
3314477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.begin_fill()
331597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.circle(60)
3316477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.end_fill()
3317477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
331897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not self.filling():
331997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._fillitem = self.screen._createpoly()
332097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.items.append(self._fillitem)
332197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._fillpath = [self._position]
332297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._newLine()
332397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
332497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.push(("beginfill", self._fillitem))
332597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
332697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
3327477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
3328477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    def end_fill(self):
332997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Fill the shape drawn after the call begin_fill().
3330477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
333197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
333297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
333397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
333497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.color("black", "red")
3335477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.begin_fill()
333697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.circle(60)
3337477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.end_fill()
3338477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
333997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.filling():
334097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if len(self._fillpath) > 2:
334197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.screen._drawpoly(self._fillitem, self._fillpath,
334297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                      fill=self._fillcolor)
334397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if self.undobuffer:
334497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    self.undobuffer.push(("dofill", self._fillitem))
334597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._fillitem = self._fillpath = None
334697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._update()
334797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
334897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def dot(self, size=None, *color):
334997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Draw a dot with diameter size, using color.
335097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
335197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argumentS:
335297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        size -- an integer >= 1 (if given)
335397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color -- a colorstring or a numeric color tuple
335497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
335597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Draw a circular dot with diameter size, using color.
335697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If size is not given, the maximum of pensize+4 and 2*pensize is used.
335797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
335897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
335997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.dot()
336097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50)
3361477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
336297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not color:
336397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if isinstance(size, (str, tuple)):
336497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                color = self._colorstr(size)
336597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                size = self._pensize + max(self._pensize, 4)
336697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
336797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                color = self._pencolor
336897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if not size:
336997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    size = self._pensize + max(self._pensize, 4)
337097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
337197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if size is None:
337297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                size = self._pensize + max(self._pensize, 4)
337397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            color = self._colorstr(color)
337497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if hasattr(self.screen, "_dot"):
337597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            item = self.screen._dot(self._position, size, color)
337697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.items.append(item)
337797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self.undobuffer:
337897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.undobuffer.push(("dot", item))
337997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
338097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pen = self.pen()
338197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self.undobuffer:
338297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.undobuffer.push(["seq"])
338397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.undobuffer.cumulate = True
338497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            try:
338597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if self.resizemode() == 'auto':
338697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    self.ht()
338797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.pendown()
338897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.pensize(size)
338997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.pencolor(color)
339097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.forward(0)
339197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            finally:
339297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.pen(pen)
339397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self.undobuffer:
339497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.undobuffer.cumulate = False
339597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
339697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _write(self, txt, align, font):
339797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Performs the writing for write()
339897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
339997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        item, end = self.screen._write(self._position, txt, align, font,
340097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                          self._pencolor)
340197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.items.append(item)
340297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
340397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.push(("wri", item))
340497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return end
340597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
340697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def write(self, arg, move=False, align="left", font=("Arial", 8, "normal")):
340797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Write text at the current turtle position.
340897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
340997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
341097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        arg -- info, which is to be written to the TurtleScreen
341197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        move (optional) -- True/False
341297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        align (optional) -- one of the strings "left", "center" or right"
341397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        font (optional) -- a triple (fontname, fontsize, fonttype)
341497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
341597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Write text - the string representation of arg - at the current
341697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle position according to align ("left", "center" or right")
341797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        and with the given font.
341897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If move is True, the pen is moved to the bottom-right corner
341997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of the text. By default, move is False.
3420477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
342197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
342297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.write('Home = ', True, align="center")
342397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.write((0,0), True)
3424477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
342597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
342697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.push(["seq"])
342797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.cumulate = True
342897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        end = self._write(str(arg), align.lower(), font)
342997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if move:
343097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            x, y = self.pos()
343197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.setpos(end, y)
343297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
343397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.cumulate = False
3434fd2ede2aa84e77dac30e297a04fc49dd3bb61c68Guido van Rossum
343597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def begin_poly(self):
343697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Start recording the vertices of a polygon.
3437477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
343897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
3439477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
344097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Start recording the vertices of a polygon. Current turtle position
344197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        is first point of polygon.
3442477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
344397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
344497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.begin_poly()
3445477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
344697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._poly = [self._position]
344797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._creatingPoly = True
3448fd2ede2aa84e77dac30e297a04fc49dd3bb61c68Guido van Rossum
344997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def end_poly(self):
345097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Stop recording the vertices of a polygon.
3451477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
345297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
3453fd2ede2aa84e77dac30e297a04fc49dd3bb61c68Guido van Rossum
345497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Stop recording the vertices of a polygon. Current turtle position is
345597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        last point of polygon. This will be connected with the first point.
3456477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
345797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
345897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.end_poly()
3459477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
346097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._creatingPoly = False
3461fd2ede2aa84e77dac30e297a04fc49dd3bb61c68Guido van Rossum
346297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def get_poly(self):
346397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the lastly recorded polygon.
3464477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
346597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
346697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
346797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
346897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> p = turtle.get_poly()
346997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.register_shape("myFavouriteShape", p)
3470477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
3471eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        ## check if there is any poly?
347297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._poly is not None:
347397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return tuple(self._poly)
3474fd2ede2aa84e77dac30e297a04fc49dd3bb61c68Guido van Rossum
347597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def getscreen(self):
347697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the TurtleScreen object, the turtle is drawing  on.
3477477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
347897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
3479fd2ede2aa84e77dac30e297a04fc49dd3bb61c68Guido van Rossum
348097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Return the TurtleScreen object, the turtle is drawing  on.
348197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        So TurtleScreen-methods can be called for that object.
3482477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
348397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
348497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> ts = turtle.getscreen()
348597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> ts
348697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        <turtle.TurtleScreen object at 0x0106B770>
348797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> ts.bgcolor("pink")
3488477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
348997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.screen
3490b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
349197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def getturtle(self):
349297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the Turtleobject itself.
3493477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
349497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
349597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
349697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Only reasonable use: as a function to return the 'anonymous turtle':
3497477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
3498477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        Example:
349997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> pet = getturtle()
350097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> pet.fd(50)
350197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> pet
350297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        <turtle.Turtle object at 0x0187D810>
350397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtles()
350497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        [<turtle.Turtle object at 0x0187D810>]
3505477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
350697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self
350797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
350897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    getpen = getturtle
350997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
351097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
351197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    ################################################################
351297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    ### screen oriented methods recurring to methods of TurtleScreen
351397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    ################################################################
351497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
351597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _delay(self, delay=None):
351697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set delay value which determines speed of turtle animation.
351797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
351897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.screen.delay(delay)
3519477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
352097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def onclick(self, fun, btn=1, add=None):
352197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-click event on this turtle on canvas.
3522477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
352397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
352497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun --  a function with two arguments, to which will be assigned
352597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                the coordinates of the clicked point on the canvas.
352697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num --  number of the mouse-button defaults to 1 (left mouse button).
352797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        add --  True or False. If True, new binding will be added, otherwise
352897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                it will replace a former binding.
3529477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
353097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example for the anonymous turtle, i. e. the procedural way:
3531477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
353297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> def turn(x, y):
353397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                left(360)
3534477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
353597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> onclick(turn) # Now clicking into the turtle will turn it.
353697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> onclick(None)  # event-binding will be removed
3537477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
353897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screen._onclick(self.turtle._item, fun, btn, add)
353997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
354097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
354197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def onrelease(self, fun, btn=1, add=None):
354297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-button-release event on this turtle on canvas.
354397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
354497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
354597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun -- a function with two arguments, to which will be assigned
354697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                the coordinates of the clicked point on the canvas.
354797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num --  number of the mouse-button defaults to 1 (left mouse button).
354897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
354997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a MyTurtle instance named joe):
355097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> class MyTurtle(Turtle):
355197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                def glow(self,x,y):
355297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                        self.fillcolor("red")
355397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                def unglow(self,x,y):
355497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                        self.fillcolor("")
355597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
355697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> joe = MyTurtle()
355797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> joe.onclick(joe.glow)
355897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> joe.onrelease(joe.unglow)
355997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ### clicking on joe turns fillcolor red,
356097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ### unclicking turns it to transparent.
356197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
356297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screen._onrelease(self.turtle._item, fun, btn, add)
356397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
3564477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
356597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def ondrag(self, fun, btn=1, add=None):
356697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-move event on this turtle on canvas.
3567477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
356897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
356997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun -- a function with two arguments, to which will be assigned
357097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis               the coordinates of the clicked point on the canvas.
357197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num -- number of the mouse-button defaults to 1 (left mouse button).
3572477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
357397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Every sequence of mouse-move-events on a turtle is preceded by a
357497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        mouse-click event on that turtle.
3575477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
357697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
357797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.ondrag(turtle.goto)
3578477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
357997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ### Subsequently clicking and dragging a Turtle will
358097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ### move it across the screen thereby producing handdrawings
358197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ### (if pen is down).
358297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
358397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screen._ondrag(self.turtle._item, fun, btn, add)
3584477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
3585477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
358697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _undo(self, action, data):
358797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Does the main part of the work for undo()
3588477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
358997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer is None:
35903c7a25a4d9ea07f2aa8e4b70fecd84e33de82c2eGuido van Rossum            return
359197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if action == "rot":
359297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            angle, degPAU = data
359397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._rotate(-angle*degPAU/self._degreesPerAU)
359497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            dummy = self.undobuffer.pop()
359597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif action == "stamp":
359697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stitem = data[0]
359797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.clearstamp(stitem)
359897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif action == "go":
359997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._undogoto(data)
360097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif action in ["wri", "dot"]:
360197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            item = data[0]
360297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen._delete(item)
360397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.items.remove(item)
360497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif action == "dofill":
360597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            item = data[0]
360697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen._drawpoly(item, ((0, 0),(0, 0),(0, 0)),
360797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                  fill="", outline="")
360897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif action == "beginfill":
360997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            item = data[0]
361097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._fillitem = self._fillpath = None
361197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if item in self.items:
361297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.screen._delete(item)
361397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.items.remove(item)
361497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif action == "pen":
361597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            TPen.pen(self, data[0])
361697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.pop()
361797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
361897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def undo(self):
361997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """undo (repeatedly) the last turtle action.
362097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
362197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
362297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
362397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        undo (repeatedly) the last turtle action.
362497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Number of available undo actions is determined by the size of
362597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        the undobuffer.
362697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
362797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
362897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> for i in range(4):
362997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                turtle.fd(50); turtle.lt(80)
363097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
363197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> for i in range(8):
363297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                turtle.undo()
363397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
363497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer is None:
363597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
363697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        item = self.undobuffer.pop()
363797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        action = item[0]
363897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        data = item[1:]
363997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if action == "seq":
364097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            while data:
364197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                item = data.pop()
364297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._undo(item[0], item[1:])
364397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
364497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._undo(action, data)
3645b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
364697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    turtlesize = shapesize
3647477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
364897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. LöwisRawPen = RawTurtle
3649477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
3650601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis###  Screen - Singleton  ########################
3651477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
3652601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwisdef Screen():
3653601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis    """Return the singleton screen object.
3654601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis    If none exists at the moment, create a new one and return it,
3655601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis    else return the existing one."""
3656601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis    if Turtle._screen is None:
3657601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        Turtle._screen = _Screen()
3658601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis    return Turtle._screen
3659601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis
3660601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwisclass _Screen(TurtleScreen):
3661b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
366297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _root = None
366397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _canvas = None
366497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _title = _CFG["title"]
3665d038ca830fd5a6bafbd24b70eb71aeae83d362d3Fred Drake
366697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self):
3667601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        # XXX there is no need for this code to be conditional,
3668601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        # as there will be only a single _Screen instance, anyway
3669601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        # XXX actually, the turtle demo is injecting root window,
3670601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        # so perhaps the conditional creation of a root should be
3671601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        # preserved (perhaps by passing it as an optional parameter)
3672601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        if _Screen._root is None:
3673601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis            _Screen._root = self._root = _Root()
3674601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis            self._root.title(_Screen._title)
367597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._root.ondestroy(self._destroy)
3676601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        if _Screen._canvas is None:
367797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            width = _CFG["width"]
367897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            height = _CFG["height"]
367997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            canvwidth = _CFG["canvwidth"]
368097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            canvheight = _CFG["canvheight"]
368197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            leftright = _CFG["leftright"]
368297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            topbottom = _CFG["topbottom"]
368397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._root.setupcanvas(width, height, canvwidth, canvheight)
3684601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis            _Screen._canvas = self._root._getcanvas()
3685601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis            TurtleScreen.__init__(self, _Screen._canvas)
3686eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            self.setup(width, height, leftright, topbottom)
368797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
368897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def setup(self, width=_CFG["width"], height=_CFG["height"],
368997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis              startx=_CFG["leftright"], starty=_CFG["topbottom"]):
369097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Set the size and position of the main window.
369197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
369297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
369397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        width: as integer a size in pixels, as float a fraction of the screen.
369497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          Default is 50% of screen.
369597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        height: as integer the height in pixels, as float a fraction of the
369697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          screen. Default is 75% of screen.
369797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        startx: if positive, starting position in pixels from the left
369897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          edge of the screen, if negative from the right edge
369997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          Default, startx=None is to center window horizontally.
370097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        starty: if positive, starting position in pixels from the top
370197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          edge of the screen, if negative from the bottom edge
370297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          Default, starty=None is to center window vertically.
370397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
370497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Screen instance named screen):
370597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.setup (width=200, height=200, startx=0, starty=0)
370697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
370797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        sets window to 200x200 pixels, in upper left of screen
370897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
370997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.setup(width=.75, height=0.5, startx=None, starty=None)
371097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
371197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        sets window to 75% of screen by 50% of screen and centers
371297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
371397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not hasattr(self._root, "set_geometry"):
371497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
371597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        sw = self._root.win_width()
371697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        sh = self._root.win_height()
371797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(width, float) and 0 <= width <= 1:
371897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            width = sw*width
371997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if startx is None:
372097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            startx = (sw - width) / 2
372197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(height, float) and 0 <= height <= 1:
372297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            height = sh*height
372397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if starty is None:
372497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            starty = (sh - height) / 2
372597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._root.set_geometry(width, height, startx, starty)
3726eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self.update()
372797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
372897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def title(self, titlestring):
372997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set title of turtle-window
373097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
373197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
373297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        titlestring -- a string, to appear in the titlebar of the
373397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                       turtle graphics window.
373497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
373597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        This is a method of Screen-class. Not available for TurtleScreen-
373697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        objects.
373797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
373897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Screen instance named screen):
373997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.title("Welcome to the turtle-zoo!")
374097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
3741601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        if _Screen._root is not None:
3742601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis            _Screen._root.title(titlestring)
3743601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        _Screen._title = titlestring
3744477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
374597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _destroy(self):
374697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        root = self._root
3747601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        if root is _Screen._root:
374897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            Turtle._pen = None
374997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            Turtle._screen = None
3750601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis            _Screen._root = None
3751601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis            _Screen._canvas = None
375297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TurtleScreen._RUNNING = True
375397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        root.destroy()
3754477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
375597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def bye(self):
375697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Shut the turtlegraphics window.
3757477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
375897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
375997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bye()
376097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
376197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._destroy()
3762477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
376397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def exitonclick(self):
376497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Go into mainloop until the mouse is clicked.
3765477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
376697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
3767477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
376897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Bind bye() method to mouseclick on TurtleScreen.
376997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If "using_IDLE" - value in configuration dictionary is False
377097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (default value), enter mainloop.
377197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If IDLE with -n switch (no subprocess) is used, this value should be
377297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        set to True in turtle.cfg. In this case IDLE's mainloop
377397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        is active also for the client script.
3774477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
377597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        This is a method of the Screen-class and not available for
377697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TurtleScreen instances.
3777477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
377897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Screen instance named screen):
377997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.exitonclick()
3780477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
378197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
378297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        def exitGracefully(x, y):
378397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            """Screen.bye() with two dummy-parameters"""
378497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.bye()
378597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.onclick(exitGracefully)
378697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if _CFG["using_IDLE"]:
378797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
378897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        try:
378997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            mainloop()
379097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        except AttributeError:
379197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            exit(0)
3792477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
3793477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
379497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass Turtle(RawTurtle):
379597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """RawTurtle auto-crating (scrolled) canvas.
3796477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
379797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    When a Turtle object is created or a function derived from some
379897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Turtle method is called a TurtleScreen object is automatically created.
379997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
380097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _pen = None
380197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _screen = None
380297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
380397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self,
380497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 shape=_CFG["shape"],
380597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 undobuffersize=_CFG["undobuffersize"],
380697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 visible=_CFG["visible"]):
380797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if Turtle._screen is None:
380897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            Turtle._screen = Screen()
380997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        RawTurtle.__init__(self, Turtle._screen,
381097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                           shape=shape,
381197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                           undobuffersize=undobuffersize,
381297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                           visible=visible)
381397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
381497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. LöwisPen = Turtle
3815477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
381697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef _getpen():
381797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Create the 'anonymous' turtle if not already present."""
381897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if Turtle._pen is None:
381997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Turtle._pen = Turtle()
382097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    return Turtle._pen
382197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
382297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef _getscreen():
382397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Create a TurtleScreen if not already present."""
382497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if Turtle._screen is None:
382597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Turtle._screen = Screen()
382697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    return Turtle._screen
382797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
382897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef write_docstringdict(filename="turtle_docstringdict"):
382997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Create and write docstring-dictionary to file.
383097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
383197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Optional argument:
383297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    filename -- a string, used as filename
383397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                default value is turtle_docstringdict
383497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
383597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Has to be called explicitely, (not used by the turtle-graphics classes)
383697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    The docstring dictionary will be written to the Python script <filname>.py
383797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    It is intended to serve as a template for translation of the docstrings
383897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    into different languages.
383997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
384097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    docsdict = {}
384197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
384297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for methodname in _tg_screen_functions:
3843601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        key = "_Screen."+methodname
384497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        docsdict[key] = eval(key).__doc__
384597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for methodname in _tg_turtle_functions:
384697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        key = "Turtle."+methodname
384797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        docsdict[key] = eval(key).__doc__
384897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
384997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    f = open("%s.py" % filename,"w")
385097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    keys = sorted([x for x in docsdict.keys()
385197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                        if x.split('.')[1] not in _alias_list])
385297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    f.write('docsdict = {\n\n')
385397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for key in keys[:-1]:
385497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        f.write('%s :\n' % repr(key))
385597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        f.write('        """%s\n""",\n\n' % docsdict[key])
385697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    key = keys[-1]
385797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    f.write('%s :\n' % repr(key))
385897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    f.write('        """%s\n"""\n\n' % docsdict[key])
385997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    f.write("}\n")
386097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    f.close()
386197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
386297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef read_docstrings(lang):
386397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Read in docstrings from lang-specific docstring dictionary.
386497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
386597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Transfer docstrings, translated to lang, from a dictionary-file
386697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    to the methods of classes Screen and Turtle and - in revised form -
386797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    to the corresponding functions.
386897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
386997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    modname = "turtle_docstringdict_%(language)s" % {'language':lang.lower()}
387097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    module = __import__(modname)
387197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    docsdict = module.docsdict
387297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for key in docsdict:
387397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        try:
387497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis#            eval(key).im_func.__doc__ = docsdict[key]
387597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            eval(key).__doc__ = docsdict[key]
387697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        except:
387797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            print("Bad docstring-entry: %s" % key)
387897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
387997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis_LANGUAGE = _CFG["language"]
388097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
388197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwistry:
388297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if _LANGUAGE != "english":
388397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        read_docstrings(_LANGUAGE)
388497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisexcept ImportError:
388597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    print("Cannot find docsdict for", _LANGUAGE)
388697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisexcept:
388797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    print ("Unknown Error when trying to import %s-docstring-dictionary" %
388897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                                  _LANGUAGE)
388997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
389097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
389197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef getmethparlist(ob):
389297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    "Get strings describing the arguments for the given object"
389397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    argText1 = argText2 = ""
389497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    # bit of a hack for methods - turn it into a function
389597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    # but we drop the "self" param.
389697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    # Try and build one for Python defined functions
389797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    argOffset = 1
389897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    counter = ob.__code__.co_argcount
389997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    items2 = list(ob.__code__.co_varnames[argOffset:counter])
390097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    realArgs = ob.__code__.co_varnames[argOffset:counter]
390197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    defaults = ob.__defaults__ or []
390297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    defaults = list(map(lambda name: "=%s" % repr(name), defaults))
390397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    defaults = [""] * (len(realArgs)-len(defaults)) + defaults
390497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    items1 = list(map(lambda arg, dflt: arg+dflt, realArgs, defaults))
390597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if ob.__code__.co_flags & 0x4:
390697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        items1.append("*"+ob.__code__.co_varnames[counter])
390797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        items2.append("*"+ob.__code__.co_varnames[counter])
390897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        counter += 1
390997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if ob.__code__.co_flags & 0x8:
391097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        items1.append("**"+ob.__code__.co_varnames[counter])
391197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        items2.append("**"+ob.__code__.co_varnames[counter])
391297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    argText1 = ", ".join(items1)
391397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    argText1 = "(%s)" % argText1
391497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    argText2 = ", ".join(items2)
391597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    argText2 = "(%s)" % argText2
391697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    return argText1, argText2
391797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
391897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef _turtle_docrevise(docstr):
391997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """To reduce docstrings from RawTurtle class for functions
3920477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    """
392197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    import re
392297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if docstr is None:
392397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return None
392497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    turtlename = _CFG["exampleturtle"]
392597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    newdocstr = docstr.replace("%s." % turtlename,"")
392697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    parexp = re.compile(r' \(.+ %s\):' % turtlename)
392797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    newdocstr = parexp.sub(":", newdocstr)
392897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    return newdocstr
392997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
393097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef _screen_docrevise(docstr):
393197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """To reduce docstrings from TurtleScreen class for functions
393297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
393397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    import re
393497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if docstr is None:
393597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return None
393697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    screenname = _CFG["examplescreen"]
393797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    newdocstr = docstr.replace("%s." % screenname,"")
393897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    parexp = re.compile(r' \(.+ %s\):' % screenname)
393997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    newdocstr = parexp.sub(":", newdocstr)
394097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    return newdocstr
394197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
394297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis## The following mechanism makes all methods of RawTurtle and Turtle available
394397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis## as functions. So we can enhance, change, add, delete methods to these
394497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis## classes and do not need to change anything here.
394597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
394697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
394797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisfor methodname in _tg_screen_functions:
3948601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis    pl1, pl2 = getmethparlist(eval('_Screen.' + methodname))
394997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if pl1 == "":
395097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        print(">>>>>>", pl1, pl2)
395197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        continue
395297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    defstr = ("def %(key)s%(pl1)s: return _getscreen().%(key)s%(pl2)s" %
395397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                   {'key':methodname, 'pl1':pl1, 'pl2':pl2})
395497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    exec(defstr)
3955601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis    eval(methodname).__doc__ = _screen_docrevise(eval('_Screen.'+methodname).__doc__)
395697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
395797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisfor methodname in _tg_turtle_functions:
395897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    pl1, pl2 = getmethparlist(eval('Turtle.' + methodname))
395997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if pl1 == "":
396097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        print(">>>>>>", pl1, pl2)
396197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        continue
396297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    defstr = ("def %(key)s%(pl1)s: return _getpen().%(key)s%(pl2)s" %
396397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                   {'key':methodname, 'pl1':pl1, 'pl2':pl2})
396497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    exec(defstr)
396597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    eval(methodname).__doc__ = _turtle_docrevise(eval('Turtle.'+methodname).__doc__)
396697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
396797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
3968eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandldone = mainloop
396997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
397097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisif __name__ == "__main__":
397197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def switchpen():
397297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isdown():
397397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pu()
397497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
397597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pd()
3976477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
397797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def demo1():
397897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Demo of old turtle.py - module"""
397997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        reset()
398097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tracer(True)
3981b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum        up()
398297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        backward(100)
3983b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum        down()
398497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # draw 3 squares; the last filled
398597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        width(3)
398697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for i in range(3):
398797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if i == 2:
398897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                begin_fill()
398997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for _ in range(4):
399097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                forward(20)
399197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                left(90)
399297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if i == 2:
399397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                color("maroon")
399497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                end_fill()
3995477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters            up()
399697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            forward(30)
3997477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters            down()
399897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        width(1)
399997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color("black")
400097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # move out of the way
400197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tracer(False)
400297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        up()
40030e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters        right(90)
400497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        forward(100)
40050e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters        right(90)
400697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        forward(100)
400797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        right(180)
400897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        down()
400997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # some text
401097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        write("startstart", 1)
401197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        write("start", 1)
401297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color("red")
401397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # staircase
401497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for i in range(5):
401597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            forward(20)
401697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            left(90)
401797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            forward(20)
401897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            right(90)
401997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # filled staircase
402097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tracer(True)
402197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        begin_fill()
402297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for i in range(5):
402397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            forward(20)
402497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            left(90)
402597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            forward(20)
402697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            right(90)
402797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        end_fill()
402897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # more text
402997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
403097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def demo2():
403197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Demo of some new features."""
403297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speed(1)
403397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        st()
403497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pensize(3)
403597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        setheading(towards(0, 0))
403697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        radius = distance(0, 0)/2.0
403797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        rt(90)
403897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for _ in range(18):
403997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            switchpen()
404097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            circle(radius, 10)
404197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        write("wait a moment...")
404297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        while undobufferentries():
404397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            undo()
404497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        reset()
404597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        lt(90)
404697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        colormode(255)
404797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        laenge = 10
404897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pencolor("green")
404997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pensize(3)
405097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        lt(180)
405197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for i in range(-2, 16):
405297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if i > 0:
405397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                begin_fill()
405497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fillcolor(255-15*i, 0, 15*i)
405597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for _ in range(3):
405697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fd(laenge)
405797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                lt(120)
405897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            end_fill()
405997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            laenge += 10
406097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            lt(15)
406197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            speed((speed()+1)%12)
406297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        #end_fill()
406397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
406497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        lt(120)
406597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pu()
406697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fd(70)
406797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        rt(30)
406897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pd()
406997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color("red","yellow")
407097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speed(0)
407197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        begin_fill()
407297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for _ in range(4):
407397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            circle(50, 90)
407497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            rt(90)
407597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            fd(30)
407697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            rt(90)
407797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        end_fill()
407897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        lt(90)
407997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pu()
408097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fd(30)
408197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pd()
408297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        shape("turtle")
408397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
408497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri = getturtle()
408597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.resizemode("auto")
408697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle = Turtle()
408797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.resizemode("auto")
408897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.shape("turtle")
408997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.reset()
409097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.left(90)
409197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.speed(0)
409297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.up()
409397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.goto(280, 40)
409497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.lt(30)
409597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.down()
409697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.speed(6)
409797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.color("blue","orange")
409897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.pensize(2)
409997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.speed(6)
4100477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        setheading(towards(turtle))
410197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        count = 1
410297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        while tri.distance(turtle) > 4:
410397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            turtle.fd(3.5)
410497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            turtle.lt(0.6)
410597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            tri.setheading(tri.towards(turtle))
410697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            tri.fd(4)
410797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if count % 20 == 0:
410897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                turtle.stamp()
410997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                tri.stamp()
411097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                switchpen()
411197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            count += 1
411297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.write("CAUGHT! ", font=("Arial", 16, "bold"), align="right")
411397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.pencolor("black")
411497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.pencolor("red")
411597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
411697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        def baba(xdummy, ydummy):
411797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            clearscreen()
411897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            bye()
411997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
412097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        time.sleep(2)
412197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
412297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        while undobufferentries():
412397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            tri.undo()
412497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            turtle.undo()
412597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.fd(50)
412697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.write("  Click me!", font = ("Courier", 12, "bold") )
412797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.onclick(baba, 1)
412897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
412997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    demo1()
4130477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    demo2()
413197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    exitonclick()
4132