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
302a389e4601a462a028fb34991704a1f92d51d0eeSandro TosiImagine a robotic turtle starting at (0, 0) in the x-y plane. After an ``import turtle``, 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
332a389e4601a462a028fb34991704a1f92d51d0eeSandro Tosicommand turtle.right(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
99e130a52d8a60229f53c8bc2ea7a1f51ee592bbd7Ezio Melottiextensions 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
111c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolskyimport inspect
11209ae544ea3a6e33418ec8ab0100fc8288eef6d13Ned Deilyimport sys
11397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
11497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisfrom os.path import isfile, split, join
11597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisfrom copy import deepcopy
116eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandlfrom tkinter import simpledialog
11797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
11897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis_tg_classes = ['ScrolledCanvas', 'TurtleScreen', 'Screen',
11997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis               'RawTurtle', 'Turtle', 'RawPen', 'Pen', 'Shape', 'Vec2D']
12097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis_tg_screen_functions = ['addshape', 'bgcolor', 'bgpic', 'bye',
12197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'clearscreen', 'colormode', 'delay', 'exitonclick', 'getcanvas',
122eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'getshapes', 'listen', 'mainloop', 'mode', 'numinput',
123eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'onkey', 'onkeypress', 'onkeyrelease', 'onscreenclick', 'ontimer',
12497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'register_shape', 'resetscreen', 'screensize', 'setup',
125eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'setworldcoordinates', 'textinput', 'title', 'tracer', 'turtles', 'update',
12697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'window_height', 'window_width']
12797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis_tg_turtle_functions = ['back', 'backward', 'begin_fill', 'begin_poly', 'bk',
12897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'circle', 'clear', 'clearstamp', 'clearstamps', 'clone', 'color',
12997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'degrees', 'distance', 'dot', 'down', 'end_fill', 'end_poly', 'fd',
13046afef330f88ddcf4106094e86f54f90dbdec390Georg Brandl        'fillcolor', 'filling', 'forward', 'get_poly', 'getpen', 'getscreen', 'get_shapepoly',
13197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'getturtle', 'goto', 'heading', 'hideturtle', 'home', 'ht', 'isdown',
13297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'isvisible', 'left', 'lt', 'onclick', 'ondrag', 'onrelease', 'pd',
13397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'pen', 'pencolor', 'pendown', 'pensize', 'penup', 'pos', 'position',
13497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'pu', 'radians', 'right', 'reset', 'resizemode', 'rt',
13597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'seth', 'setheading', 'setpos', 'setposition', 'settiltangle',
136eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'setundobuffer', 'setx', 'sety', 'shape', 'shapesize', 'shapetransform', 'shearfactor', 'showturtle',
137eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'speed', 'st', 'stamp', 'tilt', 'tiltangle', 'towards',
13897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'turtlesize', 'undo', 'undobufferentries', 'up', 'width',
13997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'write', 'xcor', 'ycor']
140eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl_tg_utilities = ['write_docstringdict', 'done']
14197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
14297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis__all__ = (_tg_classes + _tg_screen_functions + _tg_turtle_functions +
143f5ac57dc05818e4fe2ff5118680fe136937d768eTerry Jan Reedy           _tg_utilities + ['Terminator']) # + _math_functions)
14497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
14597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis_alias_list = ['addshape', 'backward', 'bk', 'fd', 'ht', 'lt', 'pd', 'pos',
14697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis               'pu', 'rt', 'seth', 'setpos', 'setposition', 'st',
14797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis               'turtlesize', 'up', 'width']
14897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
14997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis_CFG = {"width" : 0.5,               # Screen
15097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "height" : 0.75,
15197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "canvwidth" : 400,
15297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "canvheight": 300,
15397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "leftright": None,
15497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "topbottom": None,
15597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "mode": "standard",          # TurtleScreen
15697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "colormode": 1.0,
15797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "delay": 10,
15897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "undobuffersize": 1000,      # RawTurtle
15997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "shape": "classic",
16097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "pencolor" : "black",
16197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "fillcolor" : "black",
16297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "resizemode" : "noresize",
16397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "visible" : True,
16497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "language": "english",        # docstrings
16597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "exampleturtle": "turtle",
16697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "examplescreen": "screen",
16797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "title": "Python Turtle Graphics",
16897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "using_IDLE": False
16997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       }
17097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
17197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef config_dict(filename):
17297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Convert content of config-file into dictionary."""
1737dde792e62c8adeaf5d633dc89e18d16067add8eFlorent Xicluna    with open(filename, "r") as f:
1747dde792e62c8adeaf5d633dc89e18d16067add8eFlorent Xicluna        cfglines = f.readlines()
17597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    cfgdict = {}
17697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for line in cfglines:
17797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        line = line.strip()
17897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not line or line.startswith("#"):
17997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            continue
18097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        try:
18197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            key, value = line.split("=")
182cefa9172a237a56c67e8c9b302c84c1c3dffb871Serhiy Storchaka        except ValueError:
18397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            print("Bad line in config-file %s:\n%s" % (filename,line))
18497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            continue
18597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        key = key.strip()
18697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        value = value.strip()
18797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if value in ["True", "False", "None", "''", '""']:
18897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            value = eval(value)
18997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
19097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            try:
19197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if "." in value:
19297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    value = float(value)
19397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                else:
19497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    value = int(value)
195cefa9172a237a56c67e8c9b302c84c1c3dffb871Serhiy Storchaka            except ValueError:
19697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                pass # value need not be converted
19797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cfgdict[key] = value
19897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    return cfgdict
19997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
20097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef readconfig(cfgdict):
20197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Read config-files, change configuration-dict accordingly.
20297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
20397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    If there is a turtle.cfg file in the current working directory,
20497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    read it from there. If this contains an importconfig-value,
20597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    say 'myway', construct filename turtle_mayway.cfg else use
20697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    turtle.cfg and read it from the import-directory, where
20797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    turtle.py is located.
20897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Update configuration dictionary first according to config-file,
20997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    in the import directory, then according to config-file in the
21097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    current working directory.
21197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    If no config-file is found, the default configuration is used.
21297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
21397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    default_cfg = "turtle.cfg"
21497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    cfgdict1 = {}
21597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    cfgdict2 = {}
21697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if isfile(default_cfg):
21797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cfgdict1 = config_dict(default_cfg)
21897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if "importconfig" in cfgdict1:
21997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        default_cfg = "turtle_%s.cfg" % cfgdict1["importconfig"]
22097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    try:
22197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        head, tail = split(__file__)
22297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cfg_file2 = join(head, default_cfg)
223cefa9172a237a56c67e8c9b302c84c1c3dffb871Serhiy Storchaka    except Exception:
22497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cfg_file2 = ""
22597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if isfile(cfg_file2):
22697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cfgdict2 = config_dict(cfg_file2)
22797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _CFG.update(cfgdict2)
22897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _CFG.update(cfgdict1)
22997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
23097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwistry:
23197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    readconfig(_CFG)
232cefa9172a237a56c67e8c9b302c84c1c3dffb871Serhiy Storchakaexcept Exception:
23397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    print ("No configfile read, reason unknown")
23497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
23597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
23697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass Vec2D(tuple):
23797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """A 2 dimensional vector class, used as a helper class
23897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for implementing turtle graphics.
23997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    May be useful for turtle graphics programs also.
24097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Derived from tuple, so a vector is a tuple!
24197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
24297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Provides (for a, b vectors, k number):
24397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       a+b vector addition
24497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       a-b vector subtraction
24597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       a*b inner product
24697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       k*a and a*k multiplication with scalar
24797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       |a| absolute value of a
24897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       a.rotate(angle) rotation
24997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
25097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __new__(cls, x, y):
25197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return tuple.__new__(cls, (x, y))
25297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __add__(self, other):
25397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return Vec2D(self[0]+other[0], self[1]+other[1])
25497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __mul__(self, other):
25597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(other, Vec2D):
25697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self[0]*other[0]+self[1]*other[1]
25797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return Vec2D(self[0]*other, self[1]*other)
25897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __rmul__(self, other):
25997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(other, int) or isinstance(other, float):
26097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return Vec2D(self[0]*other, self[1]*other)
26197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __sub__(self, other):
26297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return Vec2D(self[0]-other[0], self[1]-other[1])
26397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __neg__(self):
26497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return Vec2D(-self[0], -self[1])
26597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __abs__(self):
26697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return (self[0]**2 + self[1]**2)**0.5
26797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def rotate(self, angle):
26897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """rotate self counterclockwise by angle
26997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
27097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        perp = Vec2D(-self[1], self[0])
27197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle = angle * math.pi / 180.0
27297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        c, s = math.cos(angle), math.sin(angle)
27397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return Vec2D(self[0]*c+perp[0]*s, self[1]*c+perp[1]*s)
27497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __getnewargs__(self):
27597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return (self[0], self[1])
27697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __repr__(self):
27797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return "(%.2f,%.2f)" % self
27897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
27997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
28097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis##############################################################################
28197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis### From here up to line    : Tkinter - Interface for turtle.py            ###
282f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson### May be replaced by an interface to some different graphics toolkit     ###
28397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis##############################################################################
28497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
28597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis## helper functions for Scrolled Canvas, to forward Canvas-methods
28697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis## to ScrolledCanvas class
28797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
28897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef __methodDict(cls, _dict):
28997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """helper function for Scrolled Canvas"""
29097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    baseList = list(cls.__bases__)
29197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    baseList.reverse()
29297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for _super in baseList:
29397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        __methodDict(_super, _dict)
29497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for key, value in cls.__dict__.items():
29597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if type(value) == types.FunctionType:
29697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            _dict[key] = value
29797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
29897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef __methods(cls):
29997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """helper function for Scrolled Canvas"""
30097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _dict = {}
30197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    __methodDict(cls, _dict)
30297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    return _dict.keys()
30397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
30497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis__stringBody = (
30597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    'def %(method)s(self, *args, **kw): return ' +
30697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    'self.%(attribute)s.%(method)s(*args, **kw)')
30797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
30897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef __forwardmethods(fromClass, toClass, toPart, exclude = ()):
30997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    ### MANY CHANGES ###
31097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _dict_1 = {}
31197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    __methodDict(toClass, _dict_1)
31297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _dict = {}
31397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    mfc = __methods(fromClass)
31497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for ex in _dict_1.keys():
31597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if ex[:1] == '_' or ex[-1:] == '_' or ex in exclude or ex in mfc:
31697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pass
31797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
31897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            _dict[ex] = _dict_1[ex]
31997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
32097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for method, func in _dict.items():
32197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        d = {'method': method, 'func': func}
32297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(toPart, str):
32397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            execString = \
32497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                __stringBody % {'method' : method, 'attribute' : toPart}
32597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        exec(execString, d)
32697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        setattr(fromClass, method, d[method])   ### NEWU!
32797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
32897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
32997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass ScrolledCanvas(TK.Frame):
33097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Modeled after the scrolled canvas class from Grayons's Tkinter book.
33197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
33297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Used as the default canvas, which pops up automatically when
33397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    using turtle graphics functions or the Turtle class.
33497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
33597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, master, width=500, height=350,
33697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                          canvwidth=600, canvheight=500):
33797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TK.Frame.__init__(self, master, width=width, height=height)
33822d297be51567eb193e792a0da52b93e9a45b9a4Martin v. Löwis        self._rootwindow = self.winfo_toplevel()
33997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.width, self.height = width, height
34097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.canvwidth, self.canvheight = canvwidth, canvheight
34197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.bg = "white"
34297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas = TK.Canvas(master, width=width, height=height,
34397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                 bg=self.bg, relief=TK.SUNKEN, borderwidth=2)
34497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.hscroll = TK.Scrollbar(master, command=self._canvas.xview,
34597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                    orient=TK.HORIZONTAL)
34697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.vscroll = TK.Scrollbar(master, command=self._canvas.yview)
34797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.configure(xscrollcommand=self.hscroll.set,
34897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                               yscrollcommand=self.vscroll.set)
34997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.rowconfigure(0, weight=1, minsize=0)
35097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.columnconfigure(0, weight=1, minsize=0)
35197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.grid(padx=1, in_ = self, pady=1, row=0,
35297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                column=0, rowspan=1, columnspan=1, sticky='news')
35397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
35497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                column=1, rowspan=1, columnspan=1, sticky='news')
35597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
35697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                column=0, rowspan=1, columnspan=1, sticky='news')
35797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.reset()
35822d297be51567eb193e792a0da52b93e9a45b9a4Martin v. Löwis        self._rootwindow.bind('<Configure>', self.onResize)
35997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
36097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def reset(self, canvwidth=None, canvheight=None, bg = None):
361f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        """Adjust canvas and scrollbars according to given canvas size."""
36297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if canvwidth:
36397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.canvwidth = canvwidth
36497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if canvheight:
36597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.canvheight = canvheight
36697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if bg:
36797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.bg = bg
36897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.config(bg=bg,
36997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                        scrollregion=(-self.canvwidth//2, -self.canvheight//2,
37097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                       self.canvwidth//2, self.canvheight//2))
37197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.xview_moveto(0.5*(self.canvwidth - self.width + 30) /
37297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                               self.canvwidth)
37397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.yview_moveto(0.5*(self.canvheight- self.height + 30) /
37497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                              self.canvheight)
37597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.adjustScrolls()
37697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
37797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
37897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def adjustScrolls(self):
37997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Adjust scrollbars according to window- and canvas-size.
38097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
38197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cwidth = self._canvas.winfo_width()
38297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cheight = self._canvas.winfo_height()
38397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.xview_moveto(0.5*(self.canvwidth-cwidth)/self.canvwidth)
38497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.yview_moveto(0.5*(self.canvheight-cheight)/self.canvheight)
38597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if cwidth < self.canvwidth or cheight < self.canvheight:
38697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
38797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              column=0, rowspan=1, columnspan=1, sticky='news')
38897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
38997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              column=1, rowspan=1, columnspan=1, sticky='news')
39097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
39197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.hscroll.grid_forget()
39297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.vscroll.grid_forget()
39397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
39497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def onResize(self, event):
39597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """self-explanatory"""
39697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.adjustScrolls()
39797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
39897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def bbox(self, *args):
39997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ 'forward' method, which canvas itself has inherited...
40097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
40197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._canvas.bbox(*args)
40297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
40397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def cget(self, *args, **kwargs):
40497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ 'forward' method, which canvas itself has inherited...
40597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
40697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._canvas.cget(*args, **kwargs)
40797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
40897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def config(self, *args, **kwargs):
40997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ 'forward' method, which canvas itself has inherited...
41097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
41197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.config(*args, **kwargs)
41297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
41397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def bind(self, *args, **kwargs):
41497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ 'forward' method, which canvas itself has inherited...
41597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
41697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.bind(*args, **kwargs)
41797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
41897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def unbind(self, *args, **kwargs):
41997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ 'forward' method, which canvas itself has inherited...
42097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
42197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.unbind(*args, **kwargs)
42297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
42397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def focus_force(self):
42497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ 'forward' method, which canvas itself has inherited...
42597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
42697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.focus_force()
42797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
42897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis__forwardmethods(ScrolledCanvas, TK.Canvas, '_canvas')
42997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
43097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
43197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass _Root(TK.Tk):
43297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Root class for Screen based on Tkinter."""
43397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self):
43497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TK.Tk.__init__(self)
43597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
43697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def setupcanvas(self, width, height, cwidth, cheight):
43797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas = ScrolledCanvas(self, width, height, cwidth, cheight)
43897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._canvas.pack(expand=1, fill="both")
43997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
44097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _getcanvas(self):
44197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._canvas
442fd2ede2aa84e77dac30e297a04fc49dd3bb61c68Guido van Rossum
44397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def set_geometry(self, width, height, startx, starty):
44497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.geometry("%dx%d%+d%+d"%(width, height, startx, starty))
445477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
44697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def ondestroy(self, destroy):
44797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.wm_protocol("WM_DELETE_WINDOW", destroy)
44897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
44997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def win_width(self):
45097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.winfo_screenwidth()
45197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
45297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def win_height(self):
45397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.winfo_screenheight()
45497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
45597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. LöwisCanvas = TK.Canvas
45697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
45797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
45897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass TurtleScreenBase(object):
45997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Provide the basic graphics functionality.
46097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       Interface between Tkinter and turtle.py.
46197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
46297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       To port turtle.py to some different graphics toolkit
46397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis       a corresponding TurtleScreenBase class has to be implemented.
46497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
46597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
46697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    @staticmethod
46797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _blankimage():
46897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """return a blank image object
46997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
47097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        img = TK.PhotoImage(width=1, height=1)
47197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        img.blank()
47297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return img
47397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
47497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    @staticmethod
47597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _image(filename):
47697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """return an image object containing the
47797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        imagedata from a gif-file named filename.
47897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
47997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return TK.PhotoImage(file=filename)
48097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
48197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, cv):
48297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv = cv
48397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(cv, ScrolledCanvas):
48497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            w = self.cv.canvwidth
48597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            h = self.cv.canvheight
48697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:  # expected: ordinary TK.Canvas
48797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            w = int(self.cv.cget("width"))
48897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            h = int(self.cv.cget("height"))
48997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.config(scrollregion = (-w//2, -h//2, w//2, h//2 ))
49097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.canvwidth = w
49197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.canvheight = h
49297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.xscale = self.yscale = 1.0
49397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
49497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _createpoly(self):
49597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Create an invisible polygon item on canvas self.cv)
49697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
49797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.cv.create_polygon((0, 0, 0, 0, 0, 0), fill="", outline="")
49897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
49997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _drawpoly(self, polyitem, coordlist, fill=None,
50097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                  outline=None, width=None, top=False):
50197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Configure polygonitem polyitem according to provided
50297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        arguments:
50397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        coordlist is sequence of coordinates
50497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fill is filling color
50597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        outline is outline color
50697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        top is a boolean value, which specifies if polyitem
50797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        will be put on top of the canvas' displaylist so it
50897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        will not be covered by other items.
50997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
51097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cl = []
51197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for x, y in coordlist:
51297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            cl.append(x * self.xscale)
51397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            cl.append(-y * self.yscale)
51497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.coords(polyitem, *cl)
51597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if fill is not None:
51697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.itemconfigure(polyitem, fill=fill)
51797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if outline is not None:
51897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.itemconfigure(polyitem, outline=outline)
51997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if width is not None:
52097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.itemconfigure(polyitem, width=width)
52197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if top:
52297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_raise(polyitem)
52397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
52497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _createline(self):
52597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Create an invisible line item on canvas self.cv)
52697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
52797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.cv.create_line(0, 0, 0, 0, fill="", width=2,
52897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                   capstyle = TK.ROUND)
52997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
53097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _drawline(self, lineitem, coordlist=None,
53197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                  fill=None, width=None, top=False):
53297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Configure lineitem according to provided arguments:
53397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        coordlist is sequence of coordinates
53497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fill is drawing color
53597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        width is width of drawn line.
53697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        top is a boolean value, which specifies if polyitem
53797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        will be put on top of the canvas' displaylist so it
53897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        will not be covered by other items.
53997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
54097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if coordlist is not None:
54197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            cl = []
54297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for x, y in coordlist:
54397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                cl.append(x * self.xscale)
54497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                cl.append(-y * self.yscale)
54597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.coords(lineitem, *cl)
54697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if fill is not None:
54797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.itemconfigure(lineitem, fill=fill)
54897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if width is not None:
54997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.itemconfigure(lineitem, width=width)
55097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if top:
55197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_raise(lineitem)
55297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
55397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _delete(self, item):
55497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Delete graphics item from canvas.
55597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If item is"all" delete all graphics items.
55697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
55797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.delete(item)
55897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
55997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _update(self):
56097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Redraw graphics items on canvas
56197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
56297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.update()
56397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
56497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _delay(self, delay):
56597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Delay subsequent canvas actions for delay ms."""
56697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.after(delay)
56797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
56897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _iscolorstring(self, color):
56997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Check if the string color is a legal Tkinter color string.
57097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
57197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        try:
57297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            rgb = self.cv.winfo_rgb(color)
57397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            ok = True
57497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        except TK.TclError:
57597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            ok = False
57697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return ok
57797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
57897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _bgcolor(self, color=None):
57997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set canvas' backgroundcolor if color is not None,
58097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else return backgroundcolor."""
58197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if color is not None:
58297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.config(bg = color)
58397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._update()
58497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
58597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self.cv.cget("bg")
58697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
58797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _write(self, pos, txt, align, font, pencolor):
58897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Write txt at pos in canvas with specified font
58997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        and color.
59097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Return text item and x-coord of right bottom corner
59197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of text's bounding box."""
59297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x, y = pos
59397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x = x * self.xscale
59497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        y = y * self.yscale
59597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        anchor = {"left":"sw", "center":"s", "right":"se" }
59697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        item = self.cv.create_text(x-1, -y, text = txt, anchor = anchor[align],
59797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                        fill = pencolor, font = font)
59897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x0, y0, x1, y1 = self.cv.bbox(item)
59997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.update()
60097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return item, x1-1
60197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
60297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis##    def _dot(self, pos, size, color):
60397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis##        """may be implemented for some other graphics toolkit"""
60497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
60597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _onclick(self, item, fun, num=1, add=None):
60697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-click event on turtle.
60797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun must be a function with two arguments, the coordinates
60897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of the clicked point on the canvas.
60997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num, the number of the mouse-button defaults to 1
61097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
61197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if fun is None:
61297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_unbind(item, "<Button-%s>" % num)
61397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
61497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            def eventfun(event):
61597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                x, y = (self.cv.canvasx(event.x)/self.xscale,
61697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                        -self.cv.canvasy(event.y)/self.yscale)
61797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fun(x, y)
61897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_bind(item, "<Button-%s>" % num, eventfun, add)
61997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
62097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _onrelease(self, item, fun, num=1, add=None):
62197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-button-release event on turtle.
62297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun must be a function with two arguments, the coordinates
62397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of the point on the canvas where mouse button is released.
62497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num, the number of the mouse-button defaults to 1
62597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
62697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If a turtle is clicked, first _onclick-event will be performed,
62797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        then _onscreensclick-event.
62897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
62997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if fun is None:
63097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_unbind(item, "<Button%s-ButtonRelease>" % num)
63197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
63297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            def eventfun(event):
63397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                x, y = (self.cv.canvasx(event.x)/self.xscale,
63497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                        -self.cv.canvasy(event.y)/self.yscale)
63597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fun(x, y)
63697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_bind(item, "<Button%s-ButtonRelease>" % num,
63797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                             eventfun, add)
63897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
63997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _ondrag(self, item, fun, num=1, add=None):
64097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-move-event (with pressed mouse button) on turtle.
64197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun must be a function with two arguments, the coordinates of the
64297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        actual mouse position on the canvas.
64397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num, the number of the mouse-button defaults to 1
64497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
64597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Every sequence of mouse-move-events on a turtle is preceded by a
64697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        mouse-click event on that turtle.
64797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
64897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if fun is None:
64997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_unbind(item, "<Button%s-Motion>" % num)
65097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
65197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            def eventfun(event):
65297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                try:
65397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    x, y = (self.cv.canvasx(event.x)/self.xscale,
65497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                           -self.cv.canvasy(event.y)/self.yscale)
65597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    fun(x, y)
656cefa9172a237a56c67e8c9b302c84c1c3dffb871Serhiy Storchaka                except Exception:
65797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    pass
65897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.tag_bind(item, "<Button%s-Motion>" % num, eventfun, add)
65997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
66097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _onscreenclick(self, fun, num=1, add=None):
66197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-click event on canvas.
66297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun must be a function with two arguments, the coordinates
66397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of the clicked point on the canvas.
66497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num, the number of the mouse-button defaults to 1
66597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
66697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If a turtle is clicked, first _onclick-event will be performed,
66797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        then _onscreensclick-event.
66897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
66997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if fun is None:
67097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.unbind("<Button-%s>" % num)
67197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
67297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            def eventfun(event):
67397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                x, y = (self.cv.canvasx(event.x)/self.xscale,
67497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                        -self.cv.canvasy(event.y)/self.yscale)
67597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fun(x, y)
67697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.bind("<Button-%s>" % num, eventfun, add)
67797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
678eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def _onkeyrelease(self, fun, key):
67997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to key-release event of key.
68097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Canvas must have focus. See method listen
68197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
68297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if fun is None:
68397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.unbind("<KeyRelease-%s>" % key, None)
68497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
68597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            def eventfun(event):
68697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fun()
68797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.bind("<KeyRelease-%s>" % key, eventfun)
68897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
689eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def _onkeypress(self, fun, key=None):
690eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """If key is given, bind fun to key-press event of key.
691eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Otherwise bind fun to any key-press.
692eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Canvas must have focus. See method listen.
693eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
694eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if fun is None:
695eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            if key is None:
696eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                self.cv.unbind("<KeyPress>", None)
697eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            else:
698eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                self.cv.unbind("<KeyPress-%s>" % key, None)
699eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        else:
700eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            def eventfun(event):
701eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                fun()
702eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            if key is None:
703eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                self.cv.bind("<KeyPress>", eventfun)
704eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            else:
705eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                self.cv.bind("<KeyPress-%s>" % key, eventfun)
706eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
70797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _listen(self):
70897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set focus on canvas (in order to collect key-events)
70997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
71097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.focus_force()
71197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
71297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _ontimer(self, fun, t):
71397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Install a timer, which calls fun after t milliseconds.
71497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
71597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if t == 0:
71697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.after_idle(fun)
71797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
71897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.after(t, fun)
71997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
72097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _createimage(self, image):
72197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Create and return image item on canvas.
72297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
72397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.cv.create_image(0, 0, image=image)
72497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
72597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _drawimage(self, item, pos, image):
72697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Configure image item as to draw image object
72797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        at position (x,y) on canvas)
72897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
72997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x, y = pos
73097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.coords(item, (x * self.xscale, -y * self.yscale))
73197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.itemconfig(item, image=image)
73297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
73397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _setbgpic(self, item, image):
73497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Configure image item as to draw image object
73597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        at center of canvas. Set item to the first item
73697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        in the displaylist, so it will be drawn below
73797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        any other item ."""
73897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.itemconfig(item, image=image)
73997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.tag_lower(item)
74097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
74197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _type(self, item):
74297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return 'line' or 'polygon' or 'image' depending on
74397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        type of item.
74497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
74597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.cv.type(item)
74697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
74797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _pointlist(self, item):
74897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """returns list of coordinate-pairs of points of item
74997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for insiders):
75097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> from turtle import *
75197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> getscreen()._pointlist(getturtle().turtle._item)
75297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        [(0.0, 9.9999999999999982), (0.0, -9.9999999999999982),
75397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (9.9999999999999982, 0.0)]
75497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> """
755022f049fededad8a2e8e902effd42eca19fbf2b1Alexander Belopolsky        cl = self.cv.coords(item)
75697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pl = [(cl[i], -cl[i+1]) for i in range(0, len(cl), 2)]
75797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return  pl
75897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
75997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _setscrollregion(self, srx1, sry1, srx2, sry2):
76097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.config(scrollregion=(srx1, sry1, srx2, sry2))
76197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
76297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _rescale(self, xscalefactor, yscalefactor):
76397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        items = self.cv.find_all()
76497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for item in items:
76597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            coordinates = list(self.cv.coords(item))
76697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            newcoordlist = []
76797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            while coordinates:
76897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                x, y = coordinates[:2]
76997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                newcoordlist.append(x * xscalefactor)
77097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                newcoordlist.append(y * yscalefactor)
77197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                coordinates = coordinates[2:]
77297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.cv.coords(item, *newcoordlist)
77397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
77497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _resize(self, canvwidth=None, canvheight=None, bg=None):
775f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        """Resize the canvas the turtles are drawing on. Does
77697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        not alter the drawing window.
77797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
77897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # needs amendment
77997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not isinstance(self.cv, ScrolledCanvas):
78097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self.canvwidth, self.canvheight
781fd1b0930ce6a84096d30c03a70cd9e0ee4a3178fFlorent Xicluna        if canvwidth is canvheight is bg is None:
78297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self.cv.canvwidth, self.cv.canvheight
78397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if canvwidth is not None:
78497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.canvwidth = canvwidth
78597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if canvheight is not None:
78697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.canvheight = canvheight
78797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cv.reset(canvwidth, canvheight, bg)
78897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
78997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _window_size(self):
79097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return the width and height of the turtle window.
79197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
79297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        width = self.cv.winfo_width()
79397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if width <= 1:  # the window isn't managed by a geometry manager
79497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            width = self.cv['width']
79597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        height = self.cv.winfo_height()
79697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if height <= 1: # the window isn't managed by a geometry manager
79797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            height = self.cv['height']
79897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return width, height
79997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
800eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def mainloop(self):
801eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Starts event loop - calling Tkinter's mainloop function.
802eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
803eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        No argument.
804eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
805eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Must be last statement in a turtle graphics program.
806eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Must NOT be used if a script is run from within IDLE in -n mode
807eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        (No subprocess) - for interactive use of turtle graphics.
808eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
809eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Example (for a TurtleScreen instance named screen):
810eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> screen.mainloop()
811eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
812eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
813eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        TK.mainloop()
814eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
815eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def textinput(self, title, prompt):
816eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Pop up a dialog window for input of a string.
817eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
818eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Arguments: title is the title of the dialog window,
819eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        prompt is a text mostly describing what information to input.
820eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
821eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Return the string input
822eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        If the dialog is canceled, return None.
823eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
824eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Example (for a TurtleScreen instance named screen):
825eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> screen.textinput("NIM", "Name of first player:")
826eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
827eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
828eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        return simpledialog.askstring(title, prompt)
829eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
830eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def numinput(self, title, prompt, default=None, minval=None, maxval=None):
831eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Pop up a dialog window for input of a number.
832eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
833eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Arguments: title is the title of the dialog window,
834eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        prompt is a text mostly describing what numerical information to input.
835eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        default: default value
836eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        minval: minimum value for imput
837eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        maxval: maximum value for input
838eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
839eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        The number input must be in the range minval .. maxval if these are
840eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        given. If not, a hint is issued and the dialog remains open for
841eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        correction. Return the number input.
842eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        If the dialog is canceled,  return None.
843eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
844eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Example (for a TurtleScreen instance named screen):
845eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> screen.numinput("Poker", "Your stakes:", 1000, minval=10, maxval=10000)
846eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
847eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
848eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        return simpledialog.askfloat(title, prompt, initialvalue=default,
849eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                                     minvalue=minval, maxvalue=maxval)
850eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
85197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
85297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis##############################################################################
85397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis###                  End of Tkinter - interface                            ###
85497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis##############################################################################
85597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
85697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
85797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass Terminator (Exception):
85897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Will be raised in TurtleScreen.update, if _RUNNING becomes False.
85997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
860c30b7b16ea03ad094917615940cd1a9ef53c4904Terry Jan Reedy    This stops execution of a turtle graphics script.
861c30b7b16ea03ad094917615940cd1a9ef53c4904Terry Jan Reedy    Main purpose: use in the Demo-Viewer turtle.Demo.py.
86297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
8634b6ea798cbb6ef6058d97794c652e4acfd2ac165Martin v. Löwis    pass
864b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
865b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
86697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass TurtleGraphicsError(Exception):
86797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Some TurtleGraphics Error
86897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
86997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
87097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
87197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass Shape(object):
87297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Data structure modeling shapes.
87397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
87497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    attribute _type is one of "polygon", "image", "compound"
87597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    attribute _data is - depending on _type a poygon-tuple,
87697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    an image or a list constructed using the addcomponent method.
87797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
87897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, type_, data=None):
87997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._type = type_
88097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if type_ == "polygon":
88197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if isinstance(data, list):
88297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                data = tuple(data)
88397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif type_ == "image":
88497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if isinstance(data, str):
88597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if data.lower().endswith(".gif") and isfile(data):
88697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    data = TurtleScreen._image(data)
88797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                # else data assumed to be Photoimage
88897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif type_ == "compound":
88997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            data = []
89097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
89197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("There is no shape type %s" % type_)
89297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._data = data
89397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
89497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def addcomponent(self, poly, fill, outline=None):
89597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Add component to a shape of type compound.
89697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
89797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments: poly is a polygon, i. e. a tuple of number pairs.
89897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fill is the fillcolor of the component,
89997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        outline is the outline color of the component.
90097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
90197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        call (for a Shapeobject namend s):
90297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --   s.addcomponent(((0,0), (10,10), (-10,10)), "red", "blue")
90397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
90497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example:
90597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
90697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> s = Shape("compound")
90797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> s.addcomponent(poly, "red", "blue")
9089aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        >>> # .. add more components and then use register_shape()
90997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
91097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._type != "compound":
91197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("Cannot add component to %s Shape"
91297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                                % self._type)
91397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if outline is None:
91497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            outline = fill
91597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._data.append([poly, fill, outline])
91697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
91797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
91897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass Tbuffer(object):
91997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Ring buffer used as undobuffer for RawTurtle objects."""
92097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, bufsize=10):
92197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.bufsize = bufsize
92297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.buffer = [[None]] * bufsize
92397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.ptr = -1
92497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.cumulate = False
92597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def reset(self, bufsize=None):
92697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if bufsize is None:
92797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for i in range(self.bufsize):
92897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.buffer[i] = [None]
92997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
93097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.bufsize = bufsize
93197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.buffer = [[None]] * bufsize
93297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.ptr = -1
93397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def push(self, item):
93497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.bufsize > 0:
93597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if not self.cumulate:
93697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.ptr = (self.ptr + 1) % self.bufsize
93797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.buffer[self.ptr] = item
93897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
93997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.buffer[self.ptr].append(item)
94097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def pop(self):
94197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.bufsize > 0:
94297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            item = self.buffer[self.ptr]
94397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if item is None:
94497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                return None
94597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
94697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.buffer[self.ptr] = [None]
94797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.ptr = (self.ptr - 1) % self.bufsize
94897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                return (item)
94997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def nr_of_items(self):
95097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.bufsize - self.buffer.count([None])
95197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __repr__(self):
95297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return str(self.buffer) + " " + str(self.ptr)
95397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
95497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
95597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
95697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass TurtleScreen(TurtleScreenBase):
95797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Provides screen oriented methods like setbg etc.
95897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
95997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Only relies upon the methods of TurtleScreenBase and NOT
96097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    upon components of the underlying graphics toolkit -
96197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    which is Tkinter in this case.
96297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
96397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _RUNNING = True
96497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
96597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, cv, mode=_CFG["mode"],
96697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 colormode=_CFG["colormode"], delay=_CFG["delay"]):
96797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._shapes = {
96897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                   "arrow" : Shape("polygon", ((-10,0), (10,0), (0,10))),
96997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                  "turtle" : Shape("polygon", ((0,16), (-2,14), (-1,10), (-4,7),
97097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (-7,9), (-9,8), (-6,5), (-7,1), (-5,-3), (-8,-6),
97197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (-6,-8), (-4,-5), (0,-7), (4,-5), (6,-8), (8,-6),
97297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (5,-3), (7,1), (6,5), (9,8), (7,9), (4,7), (1,10),
97397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (2,14))),
97497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                  "circle" : Shape("polygon", ((10,0), (9.51,3.09), (8.09,5.88),
97597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (5.88,8.09), (3.09,9.51), (0,10), (-3.09,9.51),
97697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (-5.88,8.09), (-8.09,5.88), (-9.51,3.09), (-10,0),
97797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (-9.51,-3.09), (-8.09,-5.88), (-5.88,-8.09),
97897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (-3.09,-9.51), (-0.00,-10.00), (3.09,-9.51),
97997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (5.88,-8.09), (8.09,-5.88), (9.51,-3.09))),
98097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                  "square" : Shape("polygon", ((10,-10), (10,10), (-10,10),
98197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (-10,-10))),
98297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "triangle" : Shape("polygon", ((10,-5.77), (0,11.55),
98397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              (-10,-5.77))),
98497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                  "classic": Shape("polygon", ((0,0),(-5,-9),(0,-7),(5,-9))),
98597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                   "blank" : Shape("image", self._blankimage())
98697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                  }
98797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
98897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._bgpics = {"nopic" : ""}
98997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
99097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TurtleScreenBase.__init__(self, cv)
99197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._mode = mode
99297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._delayvalue = delay
99397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._colormode = _CFG["colormode"]
99497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._keys = []
99597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.clear()
99609ae544ea3a6e33418ec8ab0100fc8288eef6d13Ned Deily        if sys.platform == 'darwin':
99709ae544ea3a6e33418ec8ab0100fc8288eef6d13Ned Deily            # Force Turtle window to the front on OS X. This is needed because
99809ae544ea3a6e33418ec8ab0100fc8288eef6d13Ned Deily            # the Turtle window will show behind the Terminal window when you
99909ae544ea3a6e33418ec8ab0100fc8288eef6d13Ned Deily            # start the demo from the command line.
1000152dfd1dac6b45177215486b68ac0ebda38dd507Ned Deily            rootwindow = cv.winfo_toplevel()
1001152dfd1dac6b45177215486b68ac0ebda38dd507Ned Deily            rootwindow.call('wm', 'attributes', '.', '-topmost', '1')
1002152dfd1dac6b45177215486b68ac0ebda38dd507Ned Deily            rootwindow.call('wm', 'attributes', '.', '-topmost', '0')
100397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
100497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def clear(self):
100597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Delete all drawings and all turtles from the TurtleScreen.
100697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
1007eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        No argument.
1008eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
1009f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        Reset empty TurtleScreen to its initial state: white background,
101097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        no backgroundimage, no eventbindings and tracing on.
101197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
101297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
10139aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        >>> screen.clear()
101497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
101597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Note: this method is not available as function.
101697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
101797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._delayvalue = _CFG["delay"]
101897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._colormode = _CFG["colormode"]
101997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._delete("all")
102097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._bgpic = self._createimage("")
102197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._bgpicname = "nopic"
1022b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum        self._tracing = 1
102397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._updatecounter = 0
102497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._turtles = []
102597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.bgcolor("white")
102697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for btn in 1, 2, 3:
102797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.onclick(None, btn)
1028eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self.onkeypress(None)
102997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for key in self._keys[:]:
103097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.onkey(None, key)
1031eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            self.onkeypress(None, key)
103297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Turtle._pen = None
103397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
103497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def mode(self, mode=None):
103597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set turtle-mode ('standard', 'logo' or 'world') and perform reset.
103697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
103797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
103899e843b48e68818c1c7475e203250e2afa1bd1f1Martin Panter        mode -- one of the strings 'standard', 'logo' or 'world'
103997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
104097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Mode 'standard' is compatible with turtle.py.
104197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Mode 'logo' is compatible with most Logo-Turtle-Graphics.
104297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Mode 'world' uses userdefined 'worldcoordinates'. *Attention*: in
104397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        this mode angles appear distorted if x/y unit-ratio doesn't equal 1.
104497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If mode is not given, return the current mode.
104597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
104697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis             Mode      Initial turtle heading     positive angles
104797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis         ------------|-------------------------|-------------------
104897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          'standard'    to the right (east)       counterclockwise
104997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            'logo'        upward    (north)         clockwise
105097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
105197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples:
105297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> mode('logo')   # resets turtle heading to north
105397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> mode()
105497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'logo'
105597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
1056fd1b0930ce6a84096d30c03a70cd9e0ee4a3178fFlorent Xicluna        if mode is None:
105797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._mode
105897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        mode = mode.lower()
105997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if mode not in ["standard", "logo", "world"]:
106097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("No turtle-graphics-mode %s" % mode)
106197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._mode = mode
106297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if mode in ["standard", "logo"]:
106397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._setscrollregion(-self.canvwidth//2, -self.canvheight//2,
106497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                       self.canvwidth//2, self.canvheight//2)
106597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.xscale = self.yscale = 1.0
1066b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum        self.reset()
1067b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
106897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def setworldcoordinates(self, llx, lly, urx, ury):
106997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set up a user defined coordinate-system.
107097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
107197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
107297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        llx -- a number, x-coordinate of lower left corner of canvas
107397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        lly -- a number, y-coordinate of lower left corner of canvas
107497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        urx -- a number, x-coordinate of upper right corner of canvas
107597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ury -- a number, y-coordinate of upper right corner of canvas
107697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
107797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set up user coodinat-system and switch to mode 'world' if necessary.
107897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        This performs a screen.reset. If mode 'world' is already active,
107997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        all drawings are redrawn according to the new coordinates.
108097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
108197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        But ATTENTION: in user-defined coordinatesystems angles may appear
108297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        distorted. (see Screen.mode())
108397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
108497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
108597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.setworldcoordinates(-10,-0.5,50,1.5)
108697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> for _ in range(36):
10879aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     left(10)
10889aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     forward(0.5)
108997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
109097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.mode() != "world":
109197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.mode("world")
109297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        xspan = float(urx - llx)
109397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        yspan = float(ury - lly)
109497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        wx, wy = self._window_size()
109597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screensize(wx-20, wy-20)
109697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        oldxscale, oldyscale = self.xscale, self.yscale
109797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.xscale = self.canvwidth / xspan
109897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.yscale = self.canvheight / yspan
109997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        srx1 = llx * self.xscale
110097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        sry1 = -ury * self.yscale
110197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        srx2 = self.canvwidth + srx1
110297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        sry2 = self.canvheight + sry1
110397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._setscrollregion(srx1, sry1, srx2, sry2)
110497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._rescale(self.xscale/oldxscale, self.yscale/oldyscale)
110597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.update()
110697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
110797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def register_shape(self, name, shape=None):
110897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Adds a turtle shape to TurtleScreen's shapelist.
110997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
111097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
111197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (1) name is the name of a gif-file and shape is None.
111297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            Installs the corresponding image shape.
111397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            !! Image-shapes DO NOT rotate when turning the turtle,
111497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            !! so they do not display the heading of the turtle!
111597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (2) name is an arbitrary string and shape is a tuple
111697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            of pairs of coordinates. Installs the corresponding
111797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            polygon shape
111897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (3) name is an arbitrary string and shape is a
111997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            (compound) Shape object. Installs the corresponding
112097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            compound shape.
112197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        To use a shape, you have to issue the command shape(shapename).
112297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
112397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        call: register_shape("turtle.gif")
112497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: register_shape("tri", ((0,0), (10,10), (-10,10)))
112597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
112697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
112797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.register_shape("triangle", ((5,-3),(0,5),(-5,-3)))
112897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
112997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
113097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if shape is None:
113197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            # image
113297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if name.lower().endswith(".gif"):
113397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                shape = Shape("image", self._image(name))
113497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
113597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                raise TurtleGraphicsError("Bad arguments for register_shape.\n"
113697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                          + "Use  help(register_shape)" )
113797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif isinstance(shape, tuple):
113897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            shape = Shape("polygon", shape)
113997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ## else shape assumed to be Shape-instance
114097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._shapes[name] = shape
114197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
114297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _colorstr(self, color):
114397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return color string corresponding to args.
114497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
114597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument may be a string or a tuple of three
114697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        numbers corresponding to actual colormode,
114797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        i.e. in the range 0<=n<=colormode.
114897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
114997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If the argument doesn't represent a color,
115097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        an error is raised.
115197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
115297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if len(color) == 1:
115397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            color = color[0]
115497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(color, str):
115597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._iscolorstring(color) or color == "":
115697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                return color
115797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
115897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                raise TurtleGraphicsError("bad color string: %s" % str(color))
115997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        try:
116097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            r, g, b = color
1161cefa9172a237a56c67e8c9b302c84c1c3dffb871Serhiy Storchaka        except (TypeError, ValueError):
116297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("bad color arguments: %s" % str(color))
116397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._colormode == 1.0:
116497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            r, g, b = [round(255.0*x) for x in (r, g, b)]
116597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)):
116697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("bad color sequence: %s" % str(color))
116797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return "#%02x%02x%02x" % (r, g, b)
116897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
116997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _color(self, cstr):
117097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not cstr.startswith("#"):
117197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return cstr
117297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if len(cstr) == 7:
117397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            cl = [int(cstr[i:i+2], 16) for i in (1, 3, 5)]
117497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif len(cstr) == 4:
117597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            cl = [16*int(cstr[h], 16) for h in cstr[1:]]
117697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
117797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("bad colorstring: %s" % cstr)
117897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return tuple([c * self._colormode/255 for c in cl])
117997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
118097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def colormode(self, cmode=None):
118197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the colormode or set it to 1.0 or 255.
118297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
118397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
118497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cmode -- one of the values 1.0 or 255
118597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
118697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        r, g, b values of colortriples have to be in range 0..cmode.
118797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
118897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
118997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.colormode()
119097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        1.0
119197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.colormode(255)
11929aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        >>> pencolor(240,160,80)
119397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
119497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if cmode is None:
119597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._colormode
119697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if cmode == 1.0:
119797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._colormode = float(cmode)
119897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif cmode == 255:
119997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._colormode = int(cmode)
120097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
120197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def reset(self):
120297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Reset all Turtles on the Screen to their initial state.
120397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
120497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
120597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
120697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
120797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.reset()
120897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
120997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for turtle in self._turtles:
121097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            turtle._setmode(self._mode)
121197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            turtle.reset()
121297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
121397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def turtles(self):
121497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the list of turtles on the screen.
121597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
121697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
121797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.turtles()
121897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        [<turtle.Turtle object at 0x00E11FB0>]
121997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
122097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._turtles
122197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
122297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def bgcolor(self, *args):
122397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set or return backgroundcolor of the TurtleScreen.
122497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
122597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments (if given): a color string or three numbers
122697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        in the range 0..colormode or a 3-tuple of such numbers.
122797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
122897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
122997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bgcolor("orange")
123097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bgcolor()
123197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'orange'
123297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bgcolor(0.5,0,0.5)
123397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bgcolor()
123497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        '#800080'
123597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
123697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if args:
123797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            color = self._colorstr(args)
123897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
123997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            color = None
124097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color = self._bgcolor(color)
124197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if color is not None:
124297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            color = self._color(color)
124397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return color
124497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
124597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def tracer(self, n=None, delay=None):
124697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Turns turtle animation on/off and set delay for update drawings.
124797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
124897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional arguments:
124997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        n -- nonnegative  integer
125097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        delay -- nonnegative  integer
125197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
125297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If n is given, only each n-th regular screen update is really performed.
125397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (Can be used to accelerate the drawing of complex graphics.)
125497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Second arguments sets delay value (see RawTurtle.delay())
125597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
125697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
125797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.tracer(8, 25)
125897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> dist = 2
125997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> for i in range(200):
12609aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     fd(dist)
12619aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     rt(90)
12629aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     dist += 2
126397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
126497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if n is None:
126597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._tracing
126697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._tracing = int(n)
126797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._updatecounter = 0
126897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if delay is not None:
126997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._delayvalue = int(delay)
127097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._tracing:
127197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.update()
127297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
127397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def delay(self, delay=None):
127497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return or set the drawing delay in milliseconds.
127597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
127697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
127797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        delay -- positive integer
127897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
127997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
128097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.delay(15)
128197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.delay()
128297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        15
128397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
128497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if delay is None:
128597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._delayvalue
128697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._delayvalue = int(delay)
128797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
128897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _incrementudc(self):
128930b9d5d3af043fc2687ad11a188a34fe355e20efEzio Melotti        """Increment update counter."""
129097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not TurtleScreen._RUNNING:
129180a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka            TurtleScreen._RUNNING = True
129297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise Terminator
129397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._tracing > 0:
129497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._updatecounter += 1
129597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._updatecounter %= self._tracing
129697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
129797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def update(self):
129897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Perform a TurtleScreen update.
129997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
1300eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        tracing = self._tracing
1301eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._tracing = True
130297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for t in self.turtles():
130397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            t._update_data()
130497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            t._drawturtle()
1305eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._tracing = tracing
130697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
130797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
130897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def window_width(self):
130997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return the width of the turtle window.
131097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
131197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
131297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.window_width()
131397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        640
131497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
131597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._window_size()[0]
131697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
131797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def window_height(self):
131897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return the height of the turtle window.
131997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
132097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
132197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.window_height()
132297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        480
132397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
132497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._window_size()[1]
132597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
132697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def getcanvas(self):
132797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the Canvas of this TurtleScreen.
132897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
132997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
133097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
133197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Screen instance named screen):
133297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> cv = screen.getcanvas()
133397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> cv
133497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        <turtle.ScrolledCanvas instance at 0x010742D8>
133597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
133697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.cv
133797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
133897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def getshapes(self):
133997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return a list of names of all currently available turtle shapes.
134097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
134197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
134297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
134397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
134497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.getshapes()
134597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ['arrow', 'blank', 'circle', ... , 'turtle']
134697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
134797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return sorted(self._shapes.keys())
134897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
134997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def onclick(self, fun, btn=1, add=None):
135097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-click event on canvas.
135197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
135297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
135397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun -- a function with two arguments, the coordinates of the
135497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis               clicked point on the canvas.
135597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num -- the number of the mouse-button, defaults to 1
135697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
13579aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        Example (for a TurtleScreen instance named screen)
135897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
13599aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        >>> screen.onclick(goto)
13609aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        >>> # Subsequently clicking into the TurtleScreen will
13619aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        >>> # make the turtle move to the clicked point.
136297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.onclick(None)
136397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
136497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._onscreenclick(fun, btn, add)
136597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
136697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def onkey(self, fun, key):
136797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to key-release event of key.
136897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
136997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
137097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun -- a function with no arguments
137197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        key -- a string: key (e.g. "a") or key-symbol (e.g. "space")
137297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
1373f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        In order to be able to register key-events, TurtleScreen
137497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        must have focus. (See method listen.)
137597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
13769aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        Example (for a TurtleScreen instance named screen):
137797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
137897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> def f():
13799aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     fd(50)
13809aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     lt(60)
13819aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...
138297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.onkey(f, "Up")
138397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.listen()
138497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
13859aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        Subsequently the turtle can be moved by repeatedly pressing
13869aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        the up-arrow key, consequently drawing a hexagon
13879aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen
138897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
1389fd1b0930ce6a84096d30c03a70cd9e0ee4a3178fFlorent Xicluna        if fun is None:
1390eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            if key in self._keys:
1391eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                self._keys.remove(key)
139297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif key not in self._keys:
139397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._keys.append(key)
1394eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._onkeyrelease(fun, key)
1395eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
1396eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def onkeypress(self, fun, key=None):
1397eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Bind fun to key-press event of key if key is given,
1398eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        or to any key-press-event if no key is given.
1399eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
1400eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Arguments:
1401eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        fun -- a function with no arguments
1402eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        key -- a string: key (e.g. "a") or key-symbol (e.g. "space")
1403eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
1404eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        In order to be able to register key-events, TurtleScreen
1405eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        must have focus. (See method listen.)
1406eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
1407eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Example (for a TurtleScreen instance named screen
1408eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        and a Turtle instance named turtle):
1409eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
1410eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> def f():
14119aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     fd(50)
14129aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     lt(60)
14139aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...
14149aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        >>> screen.onkeypress(f, "Up")
1415eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> screen.listen()
1416eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
14179aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        Subsequently the turtle can be moved by repeatedly pressing
14189aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        the up-arrow key, or by keeping pressed the up-arrow key.
14199aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        consequently drawing a hexagon.
1420eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
1421fd1b0930ce6a84096d30c03a70cd9e0ee4a3178fFlorent Xicluna        if fun is None:
1422eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            if key in self._keys:
1423eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                self._keys.remove(key)
1424eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        elif key is not None and key not in self._keys:
1425eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            self._keys.append(key)
1426eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._onkeypress(fun, key)
142797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
142897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def listen(self, xdummy=None, ydummy=None):
142997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set focus on TurtleScreen (in order to collect key-events)
143097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
143197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
143297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Dummy arguments are provided in order
143397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        to be able to pass listen to the onclick method.
143497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
143597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
143697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.listen()
143797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
143897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._listen()
143997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
144097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def ontimer(self, fun, t=0):
144197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Install a timer, which calls fun after t milliseconds.
144297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
144397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
144497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun -- a function with no arguments.
144597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        t -- a number >= 0
144697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
144797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
144897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
144997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> running = True
145097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> def f():
14519aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     if running:
14529aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...             fd(50)
14539aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...             lt(60)
14549aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...             screen.ontimer(f, 250)
14559aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...
14569aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        >>> f()   # makes the turtle marching around
145797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> running = False
145897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
145997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._ontimer(fun, t)
146097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
146197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def bgpic(self, picname=None):
146297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set background image or return name of current backgroundimage.
146397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
146497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
146597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        picname -- a string, name of a gif-file or "nopic".
146697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
146742da663e6fe7ecbb89b17d596c76812a91bb99a4Ezio Melotti        If picname is a filename, set the corresponding image as background.
146897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If picname is "nopic", delete backgroundimage, if present.
146997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If picname is None, return the filename of the current backgroundimage.
147097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
147197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
147297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bgpic()
147397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'nopic'
147497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bgpic("landscape.gif")
147597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bgpic()
147697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'landscape.gif'
147797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
147897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if picname is None:
147997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._bgpicname
148097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if picname not in self._bgpics:
148197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._bgpics[picname] = self._image(picname)
148297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._setbgpic(self._bgpic, self._bgpics[picname])
148397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._bgpicname = picname
148497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
148597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def screensize(self, canvwidth=None, canvheight=None, bg=None):
1486f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        """Resize the canvas the turtles are drawing on.
148797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
148897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional arguments:
148997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        canvwidth -- positive integer, new width of canvas in pixels
149097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        canvheight --  positive integer, new height of canvas in pixels
149113925008dc11f2a235627dc8c0440c0ce99171d9Ezio Melotti        bg -- colorstring or color-tuple, new backgroundcolor
149297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If no arguments are given, return current (canvaswidth, canvasheight)
149397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
149497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Do not alter the drawing window. To observe hidden parts of
149597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        the canvas use the scrollbars. (Can make visible those parts
149697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of a drawing, which were outside the canvas before!)
149797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
149897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
149997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.screensize(2000,1500)
15009aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        >>> # e.g. to search for an erroneously escaped turtle ;-)
150197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
150297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._resize(canvwidth, canvheight, bg)
150397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
150497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    onscreenclick = onclick
150597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    resetscreen = reset
150697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    clearscreen = clear
150797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    addshape = register_shape
1508eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    onkeyrelease = onkey
150997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
151097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass TNavigator(object):
151197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Navigation part of the RawTurtle.
151297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Implements methods for turtle movement.
151397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
151497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    START_ORIENTATION = {
151597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "standard": Vec2D(1.0, 0.0),
151697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "world"   : Vec2D(1.0, 0.0),
151797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        "logo"    : Vec2D(0.0, 1.0)  }
151897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    DEFAULT_MODE = "standard"
151997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    DEFAULT_ANGLEOFFSET = 0
152097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    DEFAULT_ANGLEORIENT = 1
152197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
152297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, mode=DEFAULT_MODE):
152397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._angleOffset = self.DEFAULT_ANGLEOFFSET
152497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._angleOrient = self.DEFAULT_ANGLEORIENT
152597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._mode = mode
152697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.undobuffer = None
152797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.degrees()
152897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._mode = None
152997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._setmode(mode)
153097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TNavigator.reset(self)
153197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
153297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def reset(self):
153397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """reset turtle to its initial values
153497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
153597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Will be overwritten by parent class
153697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
153797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._position = Vec2D(0.0, 0.0)
153897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._orient =  TNavigator.START_ORIENTATION[self._mode]
153997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
154097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _setmode(self, mode=None):
154197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set turtle-mode to 'standard', 'world' or 'logo'.
154297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
1543fd1b0930ce6a84096d30c03a70cd9e0ee4a3178fFlorent Xicluna        if mode is None:
154497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._mode
154597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if mode not in ["standard", "logo", "world"]:
154697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
154797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._mode = mode
154897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if mode in ["standard", "world"]:
154997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._angleOffset = 0
155097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._angleOrient = 1
155197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else: # mode == "logo":
155297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._angleOffset = self._fullcircle/4.
155397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._angleOrient = -1
155497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
155597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _setDegreesPerAU(self, fullcircle):
155697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Helper function for degrees() and radians()"""
155797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._fullcircle = fullcircle
155897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._degreesPerAU = 360/fullcircle
155997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._mode == "standard":
156097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._angleOffset = 0
156197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
156297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._angleOffset = fullcircle/4.
156397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
1564b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum    def degrees(self, fullcircle=360.0):
1565477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """ Set angle measurement units to degrees.
1566477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
156797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
156897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fullcircle -  a number
156997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
157097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set angle measurement units, i. e. set number
157197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of 'degrees' for a full circle. Dafault value is
157297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        360 degrees.
157397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
157497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
157597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.left(90)
157697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
157797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        90
15783cdfb123606fc1eb0af10552488ccec13a781bd0Alexander Belopolsky
15793cdfb123606fc1eb0af10552488ccec13a781bd0Alexander Belopolsky        Change angle measurement unit to grad (also known as gon,
15803cdfb123606fc1eb0af10552488ccec13a781bd0Alexander Belopolsky        grade, or gradian and equals 1/100-th of the right angle.)
15813cdfb123606fc1eb0af10552488ccec13a781bd0Alexander Belopolsky        >>> turtle.degrees(400.0)
158297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
158397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        100
158497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
158597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
158697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._setDegreesPerAU(fullcircle)
158797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
158897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def radians(self):
158997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Set the angle measurement units to radians.
159097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
159197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
159297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
159397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
159497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
159597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        90
159697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.radians()
159797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
159897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        1.5707963267948966
159997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
160097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._setDegreesPerAU(2*math.pi)
160197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
160297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _go(self, distance):
160397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """move turtle forward by specified distance"""
160497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ende = self._position + self._orient * distance
160597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._goto(ende)
160697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
160797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _rotate(self, angle):
160897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Turn turtle counterclockwise by specified angle if angle > 0."""
160997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle *= self._degreesPerAU
161097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._orient = self._orient.rotate(angle)
161197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
161297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _goto(self, end):
161397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """move turtle to position end."""
161497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._position = end
161597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
161697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def forward(self, distance):
161797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Move the turtle forward by the specified distance.
161897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
161997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: forward | fd
162097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
162197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
162297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        distance -- a number (integer or float)
162397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
162497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Move the turtle forward by the specified distance, in the direction
162597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        the turtle is headed.
162697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
162797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
162897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
162997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, 0.00)
163097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.forward(25)
163197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
163297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (25.00,0.00)
163397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.forward(-75)
163497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
163597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (-50.00,0.00)
163697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
163797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._go(distance)
163897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
163997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def back(self, distance):
164097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Move the turtle backward by distance.
164197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
164297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: back | backward | bk
164397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
164497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
164597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        distance -- a number
164697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
164797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Move the turtle backward by distance ,opposite to the direction the
164897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle is headed. Do not change the turtle's heading.
164997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
165097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
165197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
165297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, 0.00)
165397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.backward(30)
165497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
165597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (-30.00, 0.00)
165697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
165797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._go(-distance)
165897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
165997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def right(self, angle):
166097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Turn turtle right by angle units.
166197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
166297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: right | rt
166397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
166497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
166597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle -- a number (integer or float)
166697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
166797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Turn turtle right by angle units. (Units are by default degrees,
166897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        but can be set via the degrees() and radians() functions.)
166997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Angle orientation depends on mode. (See this.)
167097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
167197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
167297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
167397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        22.0
167497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.right(45)
167597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
167697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        337.0
167797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
167897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._rotate(-angle)
167997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
168097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def left(self, angle):
168197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Turn turtle left by angle units.
168297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
168397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: left | lt
168497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
168597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
168697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle -- a number (integer or float)
168797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
168897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Turn turtle left by angle units. (Units are by default degrees,
168997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        but can be set via the degrees() and radians() functions.)
169097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Angle orientation depends on mode. (See this.)
169197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
169297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
169397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
169497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        22.0
169597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.left(45)
169697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
169797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        67.0
169897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
169997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._rotate(angle)
170097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
170197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def pos(self):
170297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the turtle's current location (x,y), as a Vec2D-vector.
170397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
170497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: pos | position
170597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
170697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
170797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
170897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
170997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pos()
171097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, 240.00)
171197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
171297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._position
171397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
171497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def xcor(self):
171597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return the turtle's x coordinate.
171697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
171797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
171897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
171997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
172097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> reset()
172197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.left(60)
172297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.forward(100)
172397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> print turtle.xcor()
172497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        50.0
172597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
172697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._position[0]
172797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
172897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def ycor(self):
172997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return the turtle's y coordinate
173097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ---
173197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
173297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
173397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
173497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> reset()
173597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.left(60)
173697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.forward(100)
173797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> print turtle.ycor()
173897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        86.6025403784
173997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
174097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._position[1]
174197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
174297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
174397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def goto(self, x, y=None):
174497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Move turtle to an absolute position.
174597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
174697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: setpos | setposition | goto:
174797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
174897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
174997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x -- a number      or     a pair/vector of numbers
175097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        y -- a number             None
175197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
175297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        call: goto(x, y)         # two coordinates
175397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: goto((x, y))       # a pair (tuple) of coordinates
175497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: goto(vec)          # e.g. as returned by pos()
175597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
175697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Move turtle to an absolute position. If the pen is down,
175797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        a line will be drawn. The turtle's orientation does not change.
175897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
175997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
176097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> tp = turtle.pos()
176197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> tp
176297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, 0.00)
176397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.setpos(60,30)
176497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pos()
176597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (60.00,30.00)
176697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.setpos((20,80))
176797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pos()
176897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (20.00,80.00)
176997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.setpos(tp)
177097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pos()
177197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00,0.00)
177297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
177397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if y is None:
177497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._goto(Vec2D(*x))
177597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
177697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._goto(Vec2D(x, y))
177797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
177897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def home(self):
177997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Move turtle to the origin - coordinates (0,0).
178097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
178197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
178297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
1783f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        Move turtle to the origin - coordinates (0,0) and set its
1784f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        heading to its start-orientation (which depends on mode).
178597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
178697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
178797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.home()
178897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
178997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.goto(0, 0)
179097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.setheading(0)
179197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
179297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def setx(self, x):
179397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set the turtle's first coordinate to x
179497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
179597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
179697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x -- a number (integer or float)
179797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
179897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set the turtle's first coordinate to x, leave second coordinate
179997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        unchanged.
180097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
180197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
180297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
180397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, 240.00)
180497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.setx(10)
180597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
180697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (10.00, 240.00)
180797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
180897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._goto(Vec2D(x, self._position[1]))
180997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
181097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def sety(self, y):
181197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set the turtle's second coordinate to y
181297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
181397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
181497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        y -- a number (integer or float)
181597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
181697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set the turtle's first coordinate to x, second coordinate remains
181797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        unchanged.
181897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
181997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
182097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
182197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, 40.00)
182297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.sety(-10)
182397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.position()
182497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, -10.00)
182597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
182697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._goto(Vec2D(self._position[0], y))
182797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
182897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def distance(self, x, y=None):
182997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the distance from the turtle to (x,y) in turtle step units.
183097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
183197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
183297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x -- a number   or  a pair/vector of numbers   or   a turtle instance
183397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        y -- a number       None                            None
183497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
183597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        call: distance(x, y)         # two coordinates
183697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: distance((x, y))       # a pair (tuple) of coordinates
183797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: distance(vec)          # e.g. as returned by pos()
183897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: distance(mypen)        # where mypen is another turtle
183997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
184097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
184197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pos()
184297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00, 0.00)
184397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.distance(30,40)
184497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        50.0
184597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> pen = Turtle()
184697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> pen.forward(77)
184797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.distance(pen)
184897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        77.0
184997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
185097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if y is not None:
185197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = Vec2D(x, y)
185297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(x, Vec2D):
185397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = x
185497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif isinstance(x, tuple):
185597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = Vec2D(*x)
185697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif isinstance(x, TNavigator):
185797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = x._position
185897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return abs(pos - self._position)
185997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
186097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def towards(self, x, y=None):
186197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the angle of the line from the turtle's position to (x, y).
186297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
186397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
186497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x -- a number   or  a pair/vector of numbers   or   a turtle instance
186597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        y -- a number       None                            None
186697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
186797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        call: distance(x, y)         # two coordinates
186897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: distance((x, y))       # a pair (tuple) of coordinates
186997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: distance(vec)          # e.g. as returned by pos()
187097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: distance(mypen)        # where mypen is another turtle
187197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
187297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Return the angle, between the line from turtle-position to position
187397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        specified by x, y and the turtle's start orientation. (Depends on
187497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        modes - "standard" or "logo")
187597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
187697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
187797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pos()
187897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (10.00, 10.00)
187997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.towards(0,0)
188097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        225.0
188197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
188297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if y is not None:
188397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = Vec2D(x, y)
188497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(x, Vec2D):
188597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = x
188697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif isinstance(x, tuple):
188797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = Vec2D(*x)
188897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif isinstance(x, TNavigator):
188997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pos = x._position
189097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x, y = pos - self._position
189197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0
189297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        result /= self._degreesPerAU
189397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return (self._angleOffset + self._angleOrient*result) % self._fullcircle
189497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
189597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def heading(self):
189697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return the turtle's current heading.
189797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
189897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
189997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
190097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
190197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.left(67)
190297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
190397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        67.0
190497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
190597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        x, y = self._orient
190697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0
190797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        result /= self._degreesPerAU
190897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return (self._angleOffset + self._angleOrient*result) % self._fullcircle
190997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
191097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def setheading(self, to_angle):
191197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set the orientation of the turtle to to_angle.
191297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
191397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases:  setheading | seth
191497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
191597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
191697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        to_angle -- a number (integer or float)
191797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
191897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set the orientation of the turtle to to_angle.
191997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Here are some common directions in degrees:
192097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
192197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis         standard - mode:          logo-mode:
192297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        -------------------|--------------------
192397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           0 - east                0 - north
192497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          90 - north              90 - east
192597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis         180 - west              180 - south
192697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis         270 - south             270 - west
192797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
192897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
192997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.setheading(90)
193097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.heading()
193197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        90
193297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
193397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle = (to_angle - self.heading())*self._angleOrient
193497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        full = self._fullcircle
193597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle = (angle+full/2.)%full - full/2.
193697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._rotate(angle)
193797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
193897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def circle(self, radius, extent = None, steps = None):
193997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Draw a circle with given radius.
194097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
194197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
194297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        radius -- a number
194397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        extent (optional) -- a number
194497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        steps (optional) -- an integer
194597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
194697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Draw a circle with given radius. The center is radius units left
194797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of the turtle; extent - an angle - determines which part of the
194897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        circle is drawn. If extent is not given, draw the entire circle.
194997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If extent is not a full circle, one endpoint of the arc is the
195097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        current pen position. Draw the arc in counterclockwise direction
195197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if radius is positive, otherwise in clockwise direction. Finally
195297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        the direction of the turtle is changed by the amount of extent.
195397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
195497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        As the circle is approximated by an inscribed regular polygon,
195597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        steps determines the number of steps to use. If not given,
195697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        it will be calculated automatically. Maybe used to draw regular
195797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        polygons.
195897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
195997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        call: circle(radius)                  # full circle
196097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: circle(radius, extent)          # arc
196197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: circle(radius, extent, steps)
196297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        --or: circle(radius, steps=6)         # 6-sided polygon
196397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
196497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
196597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.circle(50)
196697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.circle(120, 180)  # semicircle
196797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
196897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
196997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.push(["seq"])
197097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.cumulate = True
197197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speed = self.speed()
197297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if extent is None:
197397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            extent = self._fullcircle
197497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if steps is None:
197597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            frac = abs(extent)/self._fullcircle
197697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
197797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        w = 1.0 * extent / steps
197897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        w2 = 0.5 * w
197997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        l = 2.0 * radius * math.sin(w2*math.pi/180.0*self._degreesPerAU)
198097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if radius < 0:
198197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            l, w, w2 = -l, -w, -w2
198297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tr = self._tracer()
198397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        dl = self._delay()
198497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if speed == 0:
198597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._tracer(0, 0)
198697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
198797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.speed(0)
198897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._rotate(w2)
198997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for i in range(steps):
199097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.speed(speed)
199197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._go(l)
199297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.speed(0)
199397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._rotate(w)
199497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._rotate(-w2)
199597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if speed == 0:
199697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._tracer(tr, dl)
199797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.speed(speed)
199897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
199997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.cumulate = False
200097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
200197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis## three dummy methods to be implemented by child class:
200297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
200397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def speed(self, s=0):
200497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """dummy method - to be overwritten by child class"""
200597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _tracer(self, a=None, b=None):
200697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """dummy method - to be overwritten by child class"""
200797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _delay(self, n=None):
200897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """dummy method - to be overwritten by child class"""
200997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
201097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    fd = forward
201197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    bk = back
201297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    backward = back
201397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    rt = right
201497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    lt = left
201597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    position = pos
201697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    setpos = goto
201797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    setposition = goto
201897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    seth = setheading
201997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
202097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
202197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass TPen(object):
202297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Drawing part of the RawTurtle.
202397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Implements drawing properties.
202497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
202597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, resizemode=_CFG["resizemode"]):
202697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._resizemode = resizemode # or "user" or "noresize"
202797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.undobuffer = None
202897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TPen._reset(self)
202997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
203097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _reset(self, pencolor=_CFG["pencolor"],
203197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                     fillcolor=_CFG["fillcolor"]):
203297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._pensize = 1
203397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._shown = True
203497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._pencolor = pencolor
203597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._fillcolor = fillcolor
203697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._drawing = True
203797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._speed = 3
2038eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._stretchfactor = (1., 1.)
2039eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._shearfactor = 0.
2040eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._tilt = 0.
2041eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._shapetrafo = (1., 0., 0., 1.)
204297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._outlinewidth = 1
204397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
204497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def resizemode(self, rmode=None):
204597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set resizemode to one of the values: "auto", "user", "noresize".
204697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
204797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (Optional) Argument:
204897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        rmode -- one of the strings "auto", "user", "noresize"
204997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
205097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Different resizemodes have the following effects:
205197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - "auto" adapts the appearance of the turtle
205297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                   corresponding to the value of pensize.
205397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - "user" adapts the appearance of the turtle according to the
205497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                   values of stretchfactor and outlinewidth (outline),
205597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                   which are set by shapesize()
205697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - "noresize" no adaption of the turtle's appearance takes place.
205797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If no argument is given, return current resizemode.
205897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        resizemode("user") is called by a call of shapesize with arguments.
205997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
206097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
206197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Turtle instance named turtle):
206297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.resizemode("noresize")
206397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.resizemode()
206497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'noresize'
206597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
206697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if rmode is None:
206797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._resizemode
206897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        rmode = rmode.lower()
206997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if rmode in ["auto", "user", "noresize"]:
207097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.pen(resizemode=rmode)
207197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
207297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def pensize(self, width=None):
207397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set or return the line thickness.
207497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
207597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases:  pensize | width
207697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
207797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
207897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        width -- positive number
207997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
208097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set the line thickness to width or return it. If resizemode is set
208197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        to "auto" and turtleshape is a polygon, that polygon is drawn with
208297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        the same line thickness. If no argument is given, current pensize
208397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        is returned.
208497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
208597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
208697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pensize()
208797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        1
20889aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        >>> turtle.pensize(10)   # from here on lines of width 10 are drawn
208997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
209097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if width is None:
209197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._pensize
209297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(pensize=width)
209397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
209497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
209597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def penup(self):
209697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Pull the pen up -- no drawing when moving.
209797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
209897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: penup | pu | up
209997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
210097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument
210197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
210297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
210397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.penup()
210497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
210597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not self._drawing:
210697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
210797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(pendown=False)
210897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
210997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def pendown(self):
211097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Pull the pen down -- drawing when moving.
211197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
211297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: pendown | pd | down
211397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
211497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
211597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
211697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
211797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pendown()
211897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
211997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._drawing:
212097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
212197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(pendown=True)
212297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
212397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def isdown(self):
212497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return True if pen is down, False if it's up.
212597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
212697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
212797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
212897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
212997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.penup()
213097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.isdown()
213197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        False
213297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pendown()
213397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.isdown()
213497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        True
213597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
213697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._drawing
213797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
213897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def speed(self, speed=None):
213997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return or set the turtle's speed.
214097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
214197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
214297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speed -- an integer in the range 0..10 or a speedstring (see below)
214397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
214497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set the turtle's speed to an integer value in the range 0 .. 10.
214597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If no argument is given: return current speed.
214697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
214797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If input is a number greater than 10 or smaller than 0.5,
214897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speed is set to 0.
214997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Speedstrings  are mapped to speedvalues in the following way:
215097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            'fastest' :  0
215197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            'fast'    :  10
215297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            'normal'  :  6
215397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            'slow'    :  3
215497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            'slowest' :  1
215597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speeds from 1 to 10 enforce increasingly faster animation of
215697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        line drawing and turtle turning.
215797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
215897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Attention:
215997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speed = 0 : *no* animation takes place. forward/back makes turtle jump
216097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        and likewise left/right make the turtle turn instantly.
216197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
216297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
216397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.speed(3)
216497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
216597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speeds = {'fastest':0, 'fast':10, 'normal':6, 'slow':3, 'slowest':1 }
216697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if speed is None:
216797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._speed
216897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if speed in speeds:
216997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            speed = speeds[speed]
217097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif 0.5 < speed < 10.5:
217197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            speed = int(round(speed))
217297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
217397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            speed = 0
217497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(speed=speed)
217597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
217697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def color(self, *args):
217797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return or set the pencolor and fillcolor.
217897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
217997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
218097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Several input formats are allowed.
218197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        They use 0, 1, 2, or 3 arguments as follows:
218297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
218397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color()
218497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            Return the current pencolor and the current fillcolor
218597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            as a pair of color specification strings as are returned
218697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            by pencolor and fillcolor.
218797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color(colorstring), color((r,g,b)), color(r,g,b)
218897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            inputs as in pencolor, set both, fillcolor and pencolor,
218997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            to the given value.
219097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color(colorstring1, colorstring2),
219197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color((r1,g1,b1), (r2,g2,b2))
219297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            equivalent to pencolor(colorstring1) and fillcolor(colorstring2)
219397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            and analogously, if the other input format is used.
219497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
219597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If turtleshape is a polygon, outline and interior of that polygon
219697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        is drawn with the newly set colors.
219797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        For mor info see: pencolor, fillcolor
219897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
219997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
220097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.color('red', 'green')
220197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.color()
220297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ('red', 'green')
220397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> colormode(255)
220497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> color((40, 80, 120), (160, 200, 240))
220597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> color()
220697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ('#285078', '#a0c8f0')
220797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
220897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if args:
220997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            l = len(args)
221097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if l == 1:
221197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                pcolor = fcolor = args[0]
221297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            elif l == 2:
221397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                pcolor, fcolor = args
221497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            elif l == 3:
221597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                pcolor = fcolor = args
221697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pcolor = self._colorstr(pcolor)
221797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            fcolor = self._colorstr(fcolor)
221897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.pen(pencolor=pcolor, fillcolor=fcolor)
221997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
222097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._color(self._pencolor), self._color(self._fillcolor)
222197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
222297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def pencolor(self, *args):
222397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return or set the pencolor.
222497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
222597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
222697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Four input formats are allowed:
222797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - pencolor()
222897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            Return the current pencolor as color specification string,
222997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            possibly in hex-number format (see example).
223097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            May be used as input to another color/pencolor/fillcolor call.
223197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - pencolor(colorstring)
223297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            s is a Tk color specification string, such as "red" or "yellow"
223397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - pencolor((r, g, b))
223497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            *a tuple* of r, g, and b, which represent, an RGB color,
223597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            and each of r, g, and b are in the range 0..colormode,
223697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            where colormode is either 1.0 or 255
223797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - pencolor(r, g, b)
223897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            r, g, and b represent an RGB color, and each of r, g, and b
223997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            are in the range 0..colormode
224097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
224197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If turtleshape is a polygon, the outline of that polygon is drawn
224297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        with the newly set pencolor.
224397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
224497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
224597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pencolor('brown')
224697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> tup = (0.2, 0.8, 0.55)
224797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pencolor(tup)
224897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pencolor()
224997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        '#33cc8c'
225097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
225197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if args:
225297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            color = self._colorstr(args)
225397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if color == self._pencolor:
225497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                return
225597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.pen(pencolor=color)
225697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
225797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._color(self._pencolor)
225897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
225997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def fillcolor(self, *args):
226097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Return or set the fillcolor.
226197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
226297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
226397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Four input formats are allowed:
226497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - fillcolor()
226597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            Return the current fillcolor as color specification string,
226697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            possibly in hex-number format (see example).
226797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            May be used as input to another color/pencolor/fillcolor call.
226897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - fillcolor(colorstring)
226997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            s is a Tk color specification string, such as "red" or "yellow"
227097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - fillcolor((r, g, b))
227197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            *a tuple* of r, g, and b, which represent, an RGB color,
227297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            and each of r, g, and b are in the range 0..colormode,
227397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            where colormode is either 1.0 or 255
227497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          - fillcolor(r, g, b)
227597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            r, g, and b represent an RGB color, and each of r, g, and b
227697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            are in the range 0..colormode
227797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
227897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If turtleshape is a polygon, the interior of that polygon is drawn
227997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        with the newly set fillcolor.
228097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
228197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
228297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fillcolor('violet')
228397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> col = turtle.pencolor()
228497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fillcolor(col)
228597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fillcolor(0, .5, 0)
228697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
228797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if args:
228897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            color = self._colorstr(args)
228997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if color == self._fillcolor:
229097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                return
229197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.pen(fillcolor=color)
229297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
229397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self._color(self._fillcolor)
229497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
229597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def showturtle(self):
229697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Makes the turtle visible.
229797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
229897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: showturtle | st
229997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
230097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
230197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
230297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
230397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.hideturtle()
230497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.showturtle()
230597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
230697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(shown=True)
230797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
230897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def hideturtle(self):
230997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Makes the turtle invisible.
231097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
231197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Aliases: hideturtle | ht
231297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
231397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
231497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
231597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        It's a good idea to do this while you're in the
231697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        middle of a complicated drawing, because hiding
231797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        the turtle speeds up the drawing observably.
231897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
231997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
232097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.hideturtle()
2321477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
232297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(shown=False)
2323b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
232497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def isvisible(self):
232597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return True if the Turtle is shown, False if it's hidden.
2326477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
232797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
232897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
232997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
233097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.hideturtle()
233197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> print turtle.isvisible():
233297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        False
2333477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
233497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self._shown
233597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
233697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def pen(self, pen=None, **pendict):
233797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return or set the pen's attributes.
233897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
233997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
234097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pen -- a dictionary with some or all of the below listed keys.
234197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            **pendict -- one or more keyword-arguments with the below
234297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                         listed keys as keywords.
234397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
234497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Return or set the pen's attributes in a 'pen-dictionary'
234597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        with the following key/value pairs:
234697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "shown"      :   True/False
234797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "pendown"    :   True/False
234897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "pencolor"   :   color-string or color-tuple
234997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "fillcolor"  :   color-string or color-tuple
235097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "pensize"    :   positive number
235197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "speed"      :   number in range 0..10
235297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "resizemode" :   "auto" or "user" or "noresize"
235397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "stretchfactor": (positive number, positive number)
2354eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl           "shearfactor":   number
235597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "outline"    :   positive number
235697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           "tilt"       :   number
235797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
2358f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        This dictionary can be used as argument for a subsequent
235997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pen()-call to restore the former pen-state. Moreover one
236097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        or more of these attributes can be provided as keyword-arguments.
236197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        This can be used to set several pen attributes in one statement.
236297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
236397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
236497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Turtle instance named turtle):
236597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10)
236697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pen()
236797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
236897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'pencolor': 'red', 'pendown': True, 'fillcolor': 'black',
2369eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'stretchfactor': (1,1), 'speed': 3, 'shearfactor': 0.0}
237097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> penstate=turtle.pen()
237197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.color("yellow","")
237297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.penup()
237397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.pen()
237497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
237597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'pencolor': 'yellow', 'pendown': False, 'fillcolor': '',
2376eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'stretchfactor': (1,1), 'speed': 3, 'shearfactor': 0.0}
237797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> p.pen(penstate, fillcolor="green")
237897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> p.pen()
237997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
238097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'pencolor': 'red', 'pendown': True, 'fillcolor': 'green',
2381eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        'stretchfactor': (1,1), 'speed': 3, 'shearfactor': 0.0}
238297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
238397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        _pd =  {"shown"         : self._shown,
238497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "pendown"       : self._drawing,
238597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "pencolor"      : self._pencolor,
238697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "fillcolor"     : self._fillcolor,
238797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "pensize"       : self._pensize,
238897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "speed"         : self._speed,
238997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "resizemode"    : self._resizemode,
239097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "stretchfactor" : self._stretchfactor,
2391eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                "shearfactor"   : self._shearfactor,
239297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "outline"       : self._outlinewidth,
239397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                "tilt"          : self._tilt
239497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis               }
239597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
239697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not (pen or pendict):
239797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return _pd
239897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
239997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(pen, dict):
240097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            p = pen
240197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
240297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            p = {}
240397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        p.update(pendict)
240497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
240597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        _p_buf = {}
240697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for key in p:
240797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            _p_buf[key] = _pd[key]
240897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
240997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
241097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.push(("pen", _p_buf))
241197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
241297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        newLine = False
241397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "pendown" in p:
241497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._drawing != p["pendown"]:
241597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                newLine = True
241697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "pencolor" in p:
241797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if isinstance(p["pencolor"], tuple):
241897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                p["pencolor"] = self._colorstr((p["pencolor"],))
241997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._pencolor != p["pencolor"]:
242097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                newLine = True
242197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "pensize" in p:
242297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._pensize != p["pensize"]:
242397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                newLine = True
242497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if newLine:
242597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._newLine()
242697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "pendown" in p:
242797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._drawing = p["pendown"]
242897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "pencolor" in p:
242997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._pencolor = p["pencolor"]
243097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "pensize" in p:
243197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._pensize = p["pensize"]
243297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "fillcolor" in p:
243397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if isinstance(p["fillcolor"], tuple):
243497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                p["fillcolor"] = self._colorstr((p["fillcolor"],))
243597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._fillcolor = p["fillcolor"]
243697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "speed" in p:
243797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._speed = p["speed"]
243897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "resizemode" in p:
243997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._resizemode = p["resizemode"]
244097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "stretchfactor" in p:
244197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            sf = p["stretchfactor"]
244297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if isinstance(sf, (int, float)):
244397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                sf = (sf, sf)
244497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._stretchfactor = sf
2445eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if "shearfactor" in p:
2446eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            self._shearfactor = p["shearfactor"]
244797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "outline" in p:
244897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._outlinewidth = p["outline"]
244997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "shown" in p:
245097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._shown = p["shown"]
245197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if "tilt" in p:
245297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._tilt = p["tilt"]
2453eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if "stretchfactor" in p or "tilt" in p or "shearfactor" in p:
2454eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            scx, scy = self._stretchfactor
2455eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            shf = self._shearfactor
2456eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            sa, ca = math.sin(self._tilt), math.cos(self._tilt)
2457eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            self._shapetrafo = ( scx*ca, scy*(shf*ca + sa),
2458eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                                -scx*sa, scy*(ca - shf*sa))
245997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
246097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
246197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis## three dummy methods to be implemented by child class:
246297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
246397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _newLine(self, usePos = True):
246497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """dummy method - to be overwritten by child class"""
246597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _update(self, count=True, forced=False):
246697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """dummy method - to be overwritten by child class"""
246797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _color(self, args):
246897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """dummy method - to be overwritten by child class"""
246997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _colorstr(self, args):
247097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """dummy method - to be overwritten by child class"""
247197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
247297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    width = pensize
247397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    up = penup
247497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    pu = penup
247597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    pd = pendown
247697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    down = pendown
247797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    st = showturtle
247897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    ht = hideturtle
247997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
248097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
248197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass _TurtleImage(object):
248297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Helper class: Datatype to store Turtle attributes
248397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
248497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
248597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, screen, shapeIndex):
248697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screen = screen
248797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._type = None
248897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._setshape(shapeIndex)
248997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
249097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _setshape(self, shapeIndex):
2491eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        screen = self.screen
249297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.shapeIndex = shapeIndex
249397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._type == "polygon" == screen._shapes[shapeIndex]._type:
249497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
249597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._type == "image" == screen._shapes[shapeIndex]._type:
249697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
249797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._type in ["image", "polygon"]:
249897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            screen._delete(self._item)
249997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif self._type == "compound":
250097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for item in self._item:
250197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._delete(item)
250297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._type = screen._shapes[shapeIndex]._type
250397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._type == "polygon":
250497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._item = screen._createpoly()
250597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif self._type == "image":
250697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._item = screen._createimage(screen._shapes["blank"]._data)
250797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif self._type == "compound":
250897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._item = [screen._createpoly() for item in
250997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                          screen._shapes[shapeIndex]._data]
251097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
251197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
251297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass RawTurtle(TPen, TNavigator):
251397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Animation part of the RawTurtle.
251497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Puts RawTurtle upon a TurtleScreen and provides tools for
2515f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson    its animation.
251697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
251797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    screens = []
251897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
251997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self, canvas=None,
252097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 shape=_CFG["shape"],
252197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 undobuffersize=_CFG["undobuffersize"],
252297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 visible=_CFG["visible"]):
2523601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        if isinstance(canvas, _Screen):
252497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen = canvas
252597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif isinstance(canvas, TurtleScreen):
252697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if canvas not in RawTurtle.screens:
252797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                RawTurtle.screens.append(canvas)
252897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen = canvas
252997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif isinstance(canvas, (ScrolledCanvas, Canvas)):
253097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for screen in RawTurtle.screens:
253197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if screen.cv == canvas:
253297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    self.screen = screen
253397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    break
253497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
253597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.screen = TurtleScreen(canvas)
253697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                RawTurtle.screens.append(self.screen)
253797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
253830b9d5d3af043fc2687ad11a188a34fe355e20efEzio Melotti            raise TurtleGraphicsError("bad canvas argument %s" % canvas)
253997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
254097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
254197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TNavigator.__init__(self, screen.mode())
254297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TPen.__init__(self)
254397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen._turtles.append(self)
254497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.drawingLineItem = screen._createline()
254597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.turtle = _TurtleImage(screen, shape)
254697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._poly = None
254797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._creatingPoly = False
254897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._fillitem = self._fillpath = None
254997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._shown = visible
255097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._hidden_from_screen = False
255197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.currentLineItem = screen._createline()
255297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.currentLine = [self._position]
255397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.items = [self.currentLineItem]
255497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.stampItems = []
255597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._undobuffersize = undobuffersize
255697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.undobuffer = Tbuffer(undobuffersize)
255797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
2558b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
2559b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum    def reset(self):
2560f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        """Delete the turtle's drawings and restore its default values.
2561477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
256297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
25639aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen
256497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Delete the turtle's drawings from the screen, re-center the turtle
256597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        and set variables to the default values.
256697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
256797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
2568477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.position()
256997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00,-22.00)
2570477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.heading()
2571477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        100.0
2572477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.reset()
2573477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.position()
257497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (0.00,0.00)
2575477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.heading()
2576477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        0.0
2577477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
257897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TNavigator.reset(self)
257997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TPen._reset(self)
258097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._clear()
258197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._drawturtle()
258297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
2583b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
258497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def setundobuffer(self, size):
258597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set or disable undobuffer.
2586477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
258797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
258897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        size -- an integer or None
25893c7a25a4d9ea07f2aa8e4b70fecd84e33de82c2eGuido van Rossum
259097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If size is an integer an empty undobuffer of given size is installed.
259197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Size gives the maximum number of turtle-actions that can be undone
259297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        by the undo() function.
259397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If size is None, no undobuffer is present.
2594477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
259597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
259697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.setundobuffer(42)
2597477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
2598854e76effaa272feed874c0e828ee679a3949dc2Raymond Hettinger        if size is None or size <= 0:
259997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer = None
260097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
260197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer = Tbuffer(size)
2602b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
260397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def undobufferentries(self):
260497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return count of entries in the undobuffer.
2605477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
260697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
260797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
260897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
260997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> while undobufferentries():
26109aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     undo()
2611477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
261297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer is None:
261397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return 0
261497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.undobuffer.nr_of_items()
261597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
261697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _clear(self):
261797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Delete all of pen's drawings"""
261897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._fillitem = self._fillpath = None
261997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for item in self.items:
262097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen._delete(item)
262197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.currentLineItem = self.screen._createline()
262297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.currentLine = []
262397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._drawing:
262497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.currentLine.append(self._position)
262597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.items = [self.currentLineItem]
262697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.clearstamps()
262797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.setundobuffer(self._undobuffersize)
2628b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
2629477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
263097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def clear(self):
263197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Delete the turtle's drawings from the screen. Do not move turtle.
2632477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
263397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
2634b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
263597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Delete the turtle's drawings from the screen. Do not move turtle.
263697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        State and position of the turtle as well as drawings of other
263797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtles are not affected.
2638477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
263997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Turtle instance named turtle):
264097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.clear()
264197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
264297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._clear()
264397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
2644477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
264597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _update_data(self):
264697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screen._incrementudc()
264797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.screen._updatecounter != 0:
264897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
264997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if len(self.currentLine)>1:
265097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen._drawline(self.currentLineItem, self.currentLine,
265197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                  self._pencolor, self._pensize)
265297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
265397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _update(self):
265497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Perform a Turtle-data update.
2655477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
265697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
265797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if screen._tracing == 0:
265897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
265997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif screen._tracing == 1:
266097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._update_data()
266197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._drawturtle()
266297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            screen._update()                  # TurtleScreenBase
266397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            screen._delay(screen._delayvalue) # TurtleScreenBase
266497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
266597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._update_data()
266697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if screen._updatecounter == 0:
266797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                for t in screen.turtles():
266897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    t._drawturtle()
266997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._update()
267097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
267197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _tracer(self, flag=None, delay=None):
267297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Turns turtle animation on/off and set delay for update drawings.
267397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
267497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional arguments:
267597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        n -- nonnegative  integer
267697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        delay -- nonnegative  integer
267797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
267897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If n is given, only each n-th regular screen update is really performed.
267997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (Can be used to accelerate the drawing of complex graphics.)
268097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Second arguments sets delay value (see RawTurtle.delay())
268197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
268297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
268397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.tracer(8, 25)
268497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> dist = 2
268597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> for i in range(200):
26869aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     turtle.fd(dist)
26879aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     turtle.rt(90)
26889aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     dist += 2
268997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
269097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.screen.tracer(flag, delay)
2691b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
269297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _color(self, args):
269397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.screen._color(args)
2694477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
269597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _colorstr(self, args):
269697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.screen._colorstr(args)
2697477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
269897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _cc(self, args):
269997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Convert colortriples to hexstrings.
2700477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
270197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(args, str):
270297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return args
270397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        try:
270497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            r, g, b = args
2705cefa9172a237a56c67e8c9b302c84c1c3dffb871Serhiy Storchaka        except (TypeError, ValueError):
270697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("bad color arguments: %s" % str(args))
270797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.screen._colormode == 1.0:
270897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            r, g, b = [round(255.0*x) for x in (r, g, b)]
270997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)):
271097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("bad color sequence: %s" % str(args))
271197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return "#%02x%02x%02x" % (r, g, b)
2712b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
271397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def clone(self):
271497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Create and return a clone of the turtle.
2715477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
271697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
2717b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
271897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Create and return a clone of the turtle with same position, heading
271997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        and turtle properties.
2720477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
272197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named mick):
272297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        mick = Turtle()
272397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        joe = mick.clone()
272497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
272597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
272697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._newLine(self._drawing)
272797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
272897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle = self.turtle
272997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screen = None
273097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.turtle = None  # too make self deepcopy-able
273197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
273297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        q = deepcopy(self)
273397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
273497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screen = screen
273597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.turtle = turtle
273697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
273797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        q.screen = screen
273897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        q.turtle = _TurtleImage(screen, self.turtle.shapeIndex)
273997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
274097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen._turtles.append(q)
274197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ttype = screen._shapes[self.turtle.shapeIndex]._type
274297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if ttype == "polygon":
274397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            q.turtle._item = screen._createpoly()
274497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif ttype == "image":
274597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            q.turtle._item = screen._createimage(screen._shapes["blank"]._data)
274697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif ttype == "compound":
274797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            q.turtle._item = [screen._createpoly() for item in
274897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                              screen._shapes[self.turtle.shapeIndex]._data]
274997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        q.currentLineItem = screen._createline()
275097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        q._update()
275197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return q
275297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
275397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def shape(self, name=None):
275497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set turtle shape to shape with given name / return current shapename.
275597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
275697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
275797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        name -- a string, which is a valid shapename
275897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
275997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set turtle shape to shape with given name or, if name is not given,
276097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return name of current shape.
276197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Shape with name must exist in the TurtleScreen's shape dictionary.
276297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Initially there are the following polygon shapes:
276397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'arrow', 'turtle', 'circle', 'square', 'triangle', 'classic'.
276497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        To learn about how to deal with shapes see Screen-method register_shape.
276597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
276697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
276797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shape()
276897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'arrow'
276997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shape("turtle")
277097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shape()
277197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        'turtle'
277297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
277397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if name is None:
277497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return self.turtle.shapeIndex
277597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not name in self.screen.getshapes():
277697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            raise TurtleGraphicsError("There is no shape named %s" % name)
277797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.turtle._setshape(name)
277897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
277997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
278097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def shapesize(self, stretch_wid=None, stretch_len=None, outline=None):
278197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set/return turtle's stretchfactors/outline. Set resizemode to "user".
278297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
278330b9d5d3af043fc2687ad11a188a34fe355e20efEzio Melotti        Optional arguments:
278497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           stretch_wid : positive number
278597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           stretch_len : positive number
278697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           outline  : positive number
278797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
278897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Return or set the pen's attributes x/y-stretchfactors and/or outline.
278997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Set resizemode to "user".
279097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If and only if resizemode is set to "user", the turtle will be displayed
279197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        stretched according to its stretchfactors:
279297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        stretch_wid is stretchfactor perpendicular to orientation
279397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        stretch_len is stretchfactor in direction of turtles orientation.
279497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        outline determines the width of the shapes's outline.
279597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
279697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Turtle instance named turtle):
279797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.resizemode("user")
279897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shapesize(5, 5, 12)
279997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shapesize(outline=8)
280097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
2801fd1b0930ce6a84096d30c03a70cd9e0ee4a3178fFlorent Xicluna        if stretch_wid is stretch_len is outline is None:
280297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stretch_wid, stretch_len = self._stretchfactor
280397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return stretch_wid, stretch_len, self._outlinewidth
2804eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if stretch_wid == 0 or stretch_len == 0:
2805eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            raise TurtleGraphicsError("stretch_wid/stretch_len must not be zero")
280697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if stretch_wid is not None:
280797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if stretch_len is None:
280897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                stretchfactor = stretch_wid, stretch_wid
280997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
281097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                stretchfactor = stretch_wid, stretch_len
281197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif stretch_len is not None:
281297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stretchfactor = self._stretchfactor[0], stretch_len
281397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
281497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stretchfactor = self._stretchfactor
281597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if outline is None:
281697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            outline = self._outlinewidth
281797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(resizemode="user",
281897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 stretchfactor=stretchfactor, outline=outline)
281997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
2820eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def shearfactor(self, shear=None):
2821eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Set or return the current shearfactor.
2822eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2823eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Optional argument: shear -- number, tangent of the shear angle
2824eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2825eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Shear the turtleshape according to the given shearfactor shear,
2826eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        which is the tangent of the shear angle. DO NOT change the
2827eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        turtle's heading (direction of movement).
2828eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        If shear is not given: return the current shearfactor, i. e. the
2829eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        tangent of the shear angle, by which lines parallel to the
2830eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        heading of the turtle are sheared.
2831eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2832eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Examples (for a Turtle instance named turtle):
2833eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shape("circle")
2834eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shapesize(5,2)
2835eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shearfactor(0.5)
2836eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shearfactor()
2837eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> 0.5
2838eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
2839eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if shear is None:
2840eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            return self._shearfactor
2841eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self.pen(resizemode="user", shearfactor=shear)
2842eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
284397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def settiltangle(self, angle):
284497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Rotate the turtleshape to point in the specified direction
284597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
2846eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Argument: angle -- number
284797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
284897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Rotate the turtleshape to point in the direction specified by angle,
284997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        regardless of its current tilt-angle. DO NOT change the turtle's
285097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        heading (direction of movement).
285197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
285297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
285397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Turtle instance named turtle):
285497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shape("circle")
285597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shapesize(5,2)
285697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.settiltangle(45)
285797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> stamp()
285897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fd(50)
285997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.settiltangle(-45)
286097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> stamp()
286197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fd(50)
2862477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
286397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tilt = -angle * self._degreesPerAU * self._angleOrient
286497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tilt = (tilt * math.pi / 180.0) % (2*math.pi)
286597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.pen(resizemode="user", tilt=tilt)
2866b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
2867eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def tiltangle(self, angle=None):
2868eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Set or return the current tilt-angle.
2869477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
2870eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Optional argument: angle -- number
2871eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2872eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Rotate the turtleshape to point in the direction specified by angle,
2873eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        regardless of its current tilt-angle. DO NOT change the turtle's
2874eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        heading (direction of movement).
2875eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        If angle is not given: return the current tilt-angle, i. e. the angle
2876eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        between the orientation of the turtleshape and the heading of the
2877eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        turtle (its direction of movement).
2878b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
2879eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Deprecated since Python 3.1
2880477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
288197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Turtle instance named turtle):
288297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shape("circle")
288397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shapesize(5,2)
288497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.tilt(45)
288597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.tiltangle()
288697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
2887eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if angle is None:
2888eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            tilt = -self._tilt * (180.0/math.pi) * self._angleOrient
2889eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            return (tilt / self._degreesPerAU) % self._fullcircle
2890eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        else:
2891eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            self.settiltangle(angle)
2892477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
289397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def tilt(self, angle):
289497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Rotate the turtleshape by angle.
2895477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
289697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
289797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle - a number
2898477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
289997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Rotate the turtleshape by angle from its current tilt-angle,
290097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        but do NOT change the turtle's heading (direction of movement).
2901477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
290297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Turtle instance named turtle):
290397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shape("circle")
290497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.shapesize(5,2)
290597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.tilt(30)
290697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fd(50)
290797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.tilt(30)
290897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fd(50)
290997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
291097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.settiltangle(angle + self.tiltangle())
2911477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
2912eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def shapetransform(self, t11=None, t12=None, t21=None, t22=None):
2913eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Set or return the current transformation matrix of the turtle shape.
2914eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2915eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Optional arguments: t11, t12, t21, t22 -- numbers.
2916eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2917eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        If none of the matrix elements are given, return the transformation
2918eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        matrix.
2919eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Otherwise set the given elements and transform the turtleshape
2920eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        according to the matrix consisting of first row t11, t12 and
2921eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        second row t21, 22.
2922eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Modify stretchfactor, shearfactor and tiltangle according to the
2923eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        given matrix.
2924eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2925eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Examples (for a Turtle instance named turtle):
2926eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shape("square")
2927eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shapesize(4,2)
2928eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shearfactor(-0.5)
2929eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shapetransform()
29309aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        (4.0, -1.0, -0.0, 2.0)
2931eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
2932eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if t11 is t12 is t21 is t22 is None:
2933eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            return self._shapetrafo
2934eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        m11, m12, m21, m22 = self._shapetrafo
2935eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if t11 is not None: m11 = t11
2936eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if t12 is not None: m12 = t12
2937eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if t21 is not None: m21 = t21
2938eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if t22 is not None: m22 = t22
2939eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if t11 * t22 - t12 * t21 == 0:
2940eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            raise TurtleGraphicsError("Bad shape transform matrix: must not be singular")
2941eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._shapetrafo = (m11, m12, m21, m22)
2942eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        alfa = math.atan2(-m21, m11) % (2 * math.pi)
2943eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        sa, ca = math.sin(alfa), math.cos(alfa)
2944eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        a11, a12, a21, a22 = (ca*m11 - sa*m21, ca*m12 - sa*m22,
2945eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                              sa*m11 + ca*m21, sa*m12 + ca*m22)
2946eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._stretchfactor = a11, a22
2947eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._shearfactor = a12/a22
2948eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self._tilt = alfa
29496dec4eae536b3e55bf18b5804eb01f8110d4bafbRaymond Hettinger        self.pen(resizemode="user")
2950eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2951eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
295297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _polytrafo(self, poly):
295397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Computes transformed polygon shapes from a shape
295497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        according to current position and heading.
295597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
295697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
295797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        p0, p1 = self._position
295897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        e0, e1 = self._orient
295997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        e = Vec2D(e0, e1 * screen.yscale / screen.xscale)
296097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        e0, e1 = (1.0 / abs(e)) * e
296197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return [(p0+(e1*x+e0*y)/screen.xscale, p1+(-e0*x+e1*y)/screen.yscale)
296297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                           for (x, y) in poly]
296397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
2964eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def get_shapepoly(self):
2965eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Return the current shape polygon as tuple of coordinate pairs.
2966eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2967eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        No argument.
2968eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2969eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        Examples (for a Turtle instance named turtle):
2970eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shape("square")
2971eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.shapetransform(4, -1, 0, 2)
2972eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        >>> turtle.get_shapepoly()
2973eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        ((50, -20), (30, 20), (-50, 20), (-30, -20))
2974eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2975eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
2976eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        shape = self.screen._shapes[self.turtle.shapeIndex]
2977eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if shape._type == "polygon":
2978eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            return self._getshapepoly(shape._data, shape._type == "compound")
2979eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        # else return None
2980eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
2981eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl    def _getshapepoly(self, polygon, compound=False):
2982eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """Calculate transformed shape polygon according to resizemode
2983eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        and shapetransform.
2984eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        """
2985eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        if self._resizemode == "user" or compound:
2986eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            t11, t12, t21, t22 = self._shapetrafo
2987eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        elif self._resizemode == "auto":
2988eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            l = max(1, self._pensize/5.0)
2989eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            t11, t12, t21, t22 = l, 0, 0, l
2990eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        elif self._resizemode == "noresize":
2991eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            return polygon
2992eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        return tuple([(t11*x + t12*y, t21*x + t22*y) for (x, y) in polygon])
2993eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl
299497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _drawturtle(self):
299597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Manages the correct rendering of the turtle with respect to
2996934896dc0977ea25dc37c13117525f2394625ceeMark Dickinson        its shape, resizemode, stretch and tilt etc."""
299797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
299897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        shape = screen._shapes[self.turtle.shapeIndex]
299997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ttype = shape._type
300097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        titem = self.turtle._item
300197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._shown and screen._updatecounter == 0 and screen._tracing > 0:
300297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._hidden_from_screen = False
300397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            tshape = shape._data
300497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if ttype == "polygon":
3005eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                if self._resizemode == "noresize": w = 1
3006eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                elif self._resizemode == "auto": w = self._pensize
3007eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                else: w =self._outlinewidth
3008eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                shape = self._polytrafo(self._getshapepoly(tshape))
300997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fc, oc = self._fillcolor, self._pencolor
301097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._drawpoly(titem, shape, fill=fc, outline=oc,
301197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                      width=w, top=True)
301297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            elif ttype == "image":
301397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._drawimage(titem, self._position, tshape)
301497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            elif ttype == "compound":
301597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                for item, (poly, fc, oc) in zip(titem, tshape):
3016eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                    poly = self._polytrafo(self._getshapepoly(poly, True))
301797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    screen._drawpoly(item, poly, fill=self._cc(fc),
3018eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                                     outline=self._cc(oc), width=self._outlinewidth, top=True)
301997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
302097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._hidden_from_screen:
3021b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum                return
302297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if ttype == "polygon":
302397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._drawpoly(titem, ((0, 0), (0, 0), (0, 0)), "", "")
302497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            elif ttype == "image":
302597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._drawimage(titem, self._position,
302697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                          screen._shapes["blank"]._data)
302797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            elif ttype == "compound":
302897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                for item in titem:
302997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    screen._drawpoly(item, ((0, 0), (0, 0), (0, 0)), "", "")
303097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._hidden_from_screen = True
303197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
303297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis##############################  stamp stuff  ###############################
303397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
303497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def stamp(self):
3035f8798f579b7fde2a4f0e9f3484b25bae4aa13eefMark Dickinson        """Stamp a copy of the turtleshape onto the canvas and return its id.
303697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
303797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
303897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
303997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Stamp a copy of the turtle shape onto the canvas at the current
304097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle position. Return a stamp_id for that stamp, which can be
304197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        used to delete it by calling clearstamp(stamp_id).
304297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
304397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
304497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.color("blue")
304597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.stamp()
304697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        13
304797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fd(50)
304897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
304997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
305097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        shape = screen._shapes[self.turtle.shapeIndex]
305197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ttype = shape._type
305297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tshape = shape._data
305397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if ttype == "polygon":
305497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stitem = screen._createpoly()
3055eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            if self._resizemode == "noresize": w = 1
3056eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            elif self._resizemode == "auto": w = self._pensize
3057eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            else: w =self._outlinewidth
3058eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            shape = self._polytrafo(self._getshapepoly(tshape))
305997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            fc, oc = self._fillcolor, self._pencolor
306097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            screen._drawpoly(stitem, shape, fill=fc, outline=oc,
306197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                  width=w, top=True)
306297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif ttype == "image":
306397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stitem = screen._createimage("")
306497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            screen._drawimage(stitem, self._position, tshape)
306597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif ttype == "compound":
306697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stitem = []
306797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for element in tshape:
306897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                item = screen._createpoly()
306997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                stitem.append(item)
307097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stitem = tuple(stitem)
307197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for item, (poly, fc, oc) in zip(stitem, tshape):
3072eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                poly = self._polytrafo(self._getshapepoly(poly, True))
307397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._drawpoly(item, poly, fill=self._cc(fc),
3074eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl                                 outline=self._cc(oc), width=self._outlinewidth, top=True)
307597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.stampItems.append(stitem)
307697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.undobuffer.push(("stamp", stitem))
307797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return stitem
307897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
307997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _clearstamp(self, stampid):
308097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """does the work for clearstamp() and clearstamps()
308197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
308297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if stampid in self.stampItems:
308397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if isinstance(stampid, tuple):
308497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                for subitem in stampid:
308597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    self.screen._delete(subitem)
308697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
308797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.screen._delete(stampid)
308897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.stampItems.remove(stampid)
308997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # Delete stampitem from undobuffer if necessary
309097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # if clearstamp is called directly.
309197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        item = ("stamp", stampid)
309297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        buf = self.undobuffer
309397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if item not in buf.buffer:
309497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
309597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        index = buf.buffer.index(item)
309697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        buf.buffer.remove(item)
309797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if index <= buf.ptr:
309897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            buf.ptr = (buf.ptr - 1) % buf.bufsize
309997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        buf.buffer.insert((buf.ptr+1)%buf.bufsize, [None])
310097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
310197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def clearstamp(self, stampid):
310297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Delete stamp with given stampid
310397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
310497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
310597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        stampid - an integer, must be return value of previous stamp() call.
310697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
310797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
310897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.color("blue")
310997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> astamp = turtle.stamp()
311097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fd(50)
311197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.clearstamp(astamp)
311297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
311397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._clearstamp(stampid)
311497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
311597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
311697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def clearstamps(self, n=None):
311797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Delete all or first/last n of turtle's stamps.
311897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
311997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Optional argument:
312097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        n -- an integer
312197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
312297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If n is None, delete all of pen's stamps,
312397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else if n > 0 delete first n stamps
312497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else if n < 0 delete last n stamps.
312597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
312697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
312797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> for i in range(8):
31289aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     turtle.stamp(); turtle.fd(30)
312997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ...
313097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.clearstamps(2)
313197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.clearstamps(-2)
313297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.clearstamps()
313397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
313497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if n is None:
313597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            toDelete = self.stampItems[:]
313697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif n >= 0:
313797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            toDelete = self.stampItems[:n]
3138b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum        else:
313997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            toDelete = self.stampItems[n:]
314097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for item in toDelete:
314197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._clearstamp(item)
314297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
314397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
314497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _goto(self, end):
314597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Move the pen to the point end, thereby drawing a line
314630b9d5d3af043fc2687ad11a188a34fe355e20efEzio Melotti        if pen is down. All other methods for turtle movement depend
314797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        on this one.
314897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
31491842d0c4d88fffb5bea53b410acb77796b66bc8bAlexander Belopolsky        ## Version with undo-stuff
315097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        go_modes = ( self._drawing,
315197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                     self._pencolor,
315297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                     self._pensize,
315397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                     isinstance(self._fillpath, list))
315497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
315597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        undo_entry = ("go", self._position, end, go_modes,
315697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                      (self.currentLineItem,
315797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                      self.currentLine[:],
315897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                      screen._pointlist(self.currentLineItem),
315997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                      self.items[:])
316097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                      )
316197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
316297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.push(undo_entry)
316397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        start = self._position
316497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._speed and screen._tracing == 1:
316597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            diff = (end-start)
316697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2
316797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
316897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            delta = diff * (1.0/nhops)
316997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for n in range(1, nhops):
317097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if n == 1:
317197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    top = True
317297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                else:
317397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    top = False
317497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._position = start + delta * n
317597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if self._drawing:
317697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    screen._drawline(self.drawingLineItem,
317797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                     (start, self._position),
317897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                     self._pencolor, self._pensize, top)
317997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._update()
318097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._drawing:
318197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
318297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                               fill="", width=self._pensize)
318397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # Turtle now at end,
318497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._drawing: # now update currentLine
318597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.currentLine.append(end)
318697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(self._fillpath, list):
318797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._fillpath.append(end)
318897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ######    vererbung!!!!!!!!!!!!!!!!!!!!!!
318997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._position = end
319097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._creatingPoly:
319197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._poly.append(end)
319297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if len(self.currentLine) > 42: # 42! answer to the ultimate question
319397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                       # of life, the universe and everything
319497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._newLine()
319597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update() #count=True)
319697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
319797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _undogoto(self, entry):
319897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Reverse a _goto. Used for undo()
319997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
320097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        old, new, go_modes, coodata = entry
320197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        drawing, pc, ps, filling = go_modes
320297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        cLI, cL, pl, items = coodata
320397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen = self.screen
320497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if abs(self._position - new) > 0.5:
320597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            print ("undogoto: HALLO-DA-STIMMT-WAS-NICHT!")
320697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # restore former situation
320797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.currentLineItem = cLI
320897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.currentLine = cL
320997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
321097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if pl == [(0, 0), (0, 0)]:
321197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            usepc = ""
321297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
321397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            usepc = pc
321497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        screen._drawline(cLI, pl, fill=usepc, width=ps)
321597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
321697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        todelete = [i for i in self.items if (i not in items) and
321797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                       (screen._type(i) == "line")]
321897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for i in todelete:
321997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            screen._delete(i)
322097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.items.remove(i)
322197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
322297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        start = old
322397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._speed and screen._tracing == 1:
322497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            diff = old - new
322597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2
322697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
322797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            delta = diff * (1.0/nhops)
322897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for n in range(1, nhops):
322997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if n == 1:
323097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    top = True
323197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                else:
323297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    top = False
323397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._position = new + delta * n
323497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if drawing:
323597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    screen._drawline(self.drawingLineItem,
323697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                     (start, self._position),
323797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                     pc, ps, top)
323897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._update()
323997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if drawing:
324097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
324197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                               fill="", width=ps)
324297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # Turtle now at position old,
324397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._position = old
324413925008dc11f2a235627dc8c0440c0ce99171d9Ezio Melotti        ##  if undo is done during creating a polygon, the last vertex
324513925008dc11f2a235627dc8c0440c0ce99171d9Ezio Melotti        ##  will be deleted. if the polygon is entirely deleted,
324613925008dc11f2a235627dc8c0440c0ce99171d9Ezio Melotti        ##  creatingPoly will be set to False.
324797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        ##  Polygons created before the last one will not be affected by undo()
324897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._creatingPoly:
324997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if len(self._poly) > 0:
325097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._poly.pop()
325197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._poly == []:
325297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._creatingPoly = False
325397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._poly = None
325497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if filling:
325597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self._fillpath == []:
325697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._fillpath = None
325797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                print("Unwahrscheinlich in _undogoto!")
325897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            elif self._fillpath is not None:
325997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._fillpath.pop()
326097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update() #count=True)
326197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
326297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _rotate(self, angle):
326397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Turns pen clockwise by angle.
326497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
326597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
326697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.push(("rot", angle, self._degreesPerAU))
326797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        angle *= self._degreesPerAU
326897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        neworient = self._orient.rotate(angle)
326997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tracing = self.screen._tracing
327097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if tracing == 1 and self._speed > 0:
327197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            anglevel = 3.0 * self._speed
327297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            steps = 1 + int(abs(angle)/anglevel)
327397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            delta = 1.0*angle/steps
327497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for _ in range(steps):
327597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._orient = self._orient.rotate(delta)
327697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._update()
327797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._orient = neworient
327897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
327997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
328097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _newLine(self, usePos=True):
328197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Closes current line item and starts a new one.
328297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           Remark: if current line became too long, animation
328397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis           performance (via _drawline) slowed down considerably.
328497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
328597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if len(self.currentLine) > 1:
328697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen._drawline(self.currentLineItem, self.currentLine,
328797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                      self._pencolor, self._pensize)
328897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.currentLineItem = self.screen._createline()
328997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.items.append(self.currentLineItem)
329097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
329197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen._drawline(self.currentLineItem, top=True)
329297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.currentLine = []
329397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if usePos:
329497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.currentLine = [self._position]
3295477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
329697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def filling(self):
329797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return fillstate (True if filling, False else).
3298b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
329997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
3300477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
330197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
330297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.begin_fill()
330397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> if turtle.filling():
33049aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     turtle.pensize(5)
33059aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ... else:
33069aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     turtle.pensize(3)
330797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
330897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return isinstance(self._fillpath, list)
330997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
3310477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    def begin_fill(self):
331197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Called just before drawing a shape to be filled.
3312477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
331397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
331497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
331597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
331697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.color("black", "red")
3317477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.begin_fill()
331897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.circle(60)
3319477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.end_fill()
3320477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
332197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not self.filling():
332297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._fillitem = self.screen._createpoly()
332397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.items.append(self._fillitem)
332497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._fillpath = [self._position]
332597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._newLine()
332697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
332797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.push(("beginfill", self._fillitem))
332897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
332997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
3330477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
3331477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    def end_fill(self):
333297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Fill the shape drawn after the call begin_fill().
3333477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
333497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
333597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
333697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
333797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.color("black", "red")
3338477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.begin_fill()
333997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.circle(60)
3340477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        >>> turtle.end_fill()
3341477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
334297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.filling():
334397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if len(self._fillpath) > 2:
334497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.screen._drawpoly(self._fillitem, self._fillpath,
334597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                      fill=self._fillcolor)
334697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if self.undobuffer:
334797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    self.undobuffer.push(("dofill", self._fillitem))
334897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._fillitem = self._fillpath = None
334997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._update()
335097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
335197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def dot(self, size=None, *color):
335297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Draw a dot with diameter size, using color.
335397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
335442da663e6fe7ecbb89b17d596c76812a91bb99a4Ezio Melotti        Optional arguments:
335597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        size -- an integer >= 1 (if given)
335697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color -- a colorstring or a numeric color tuple
335797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
335897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Draw a circular dot with diameter size, using color.
335997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If size is not given, the maximum of pensize+4 and 2*pensize is used.
336097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
336197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
336297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.dot()
336397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50)
3364477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
336597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not color:
336697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if isinstance(size, (str, tuple)):
336797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                color = self._colorstr(size)
336897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                size = self._pensize + max(self._pensize, 4)
336997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            else:
337097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                color = self._pencolor
337197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if not size:
337297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    size = self._pensize + max(self._pensize, 4)
337397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
337497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if size is None:
337597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                size = self._pensize + max(self._pensize, 4)
337697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            color = self._colorstr(color)
337797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if hasattr(self.screen, "_dot"):
337897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            item = self.screen._dot(self._position, size, color)
337997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.items.append(item)
338097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self.undobuffer:
338197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.undobuffer.push(("dot", item))
338297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
338397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pen = self.pen()
338497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self.undobuffer:
338597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.undobuffer.push(["seq"])
338697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.undobuffer.cumulate = True
338797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            try:
338897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                if self.resizemode() == 'auto':
338997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                    self.ht()
339097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.pendown()
339197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.pensize(size)
339297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.pencolor(color)
339397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.forward(0)
339497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            finally:
339597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.pen(pen)
339697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if self.undobuffer:
339797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.undobuffer.cumulate = False
339897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
339997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _write(self, txt, align, font):
340097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Performs the writing for write()
340197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
340297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        item, end = self.screen._write(self._position, txt, align, font,
340397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                          self._pencolor)
340497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.items.append(item)
340597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
340697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.push(("wri", item))
340797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return end
340897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
340997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def write(self, arg, move=False, align="left", font=("Arial", 8, "normal")):
341097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Write text at the current turtle position.
341197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
341297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
341397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        arg -- info, which is to be written to the TurtleScreen
341497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        move (optional) -- True/False
341597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        align (optional) -- one of the strings "left", "center" or right"
341697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        font (optional) -- a triple (fontname, fontsize, fonttype)
341797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
341897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Write text - the string representation of arg - at the current
341997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle position according to align ("left", "center" or right")
342097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        and with the given font.
342197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If move is True, the pen is moved to the bottom-right corner
342297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        of the text. By default, move is False.
3423477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
342497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
342597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.write('Home = ', True, align="center")
342697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.write((0,0), True)
3427477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
342897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
342997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.push(["seq"])
343097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.cumulate = True
343197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        end = self._write(str(arg), align.lower(), font)
343297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if move:
343397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            x, y = self.pos()
343497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.setpos(end, y)
343597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer:
343697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.cumulate = False
3437fd2ede2aa84e77dac30e297a04fc49dd3bb61c68Guido van Rossum
343897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def begin_poly(self):
343997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Start recording the vertices of a polygon.
3440477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
344197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
3442477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
344397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Start recording the vertices of a polygon. Current turtle position
344497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        is first point of polygon.
3445477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
344697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
344797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.begin_poly()
3448477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
344997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._poly = [self._position]
345097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._creatingPoly = True
3451fd2ede2aa84e77dac30e297a04fc49dd3bb61c68Guido van Rossum
345297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def end_poly(self):
345397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Stop recording the vertices of a polygon.
3454477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
345597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
3456fd2ede2aa84e77dac30e297a04fc49dd3bb61c68Guido van Rossum
345797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Stop recording the vertices of a polygon. Current turtle position is
345897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        last point of polygon. This will be connected with the first point.
3459477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
346097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
346197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.end_poly()
3462477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
346397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._creatingPoly = False
3464fd2ede2aa84e77dac30e297a04fc49dd3bb61c68Guido van Rossum
346597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def get_poly(self):
346697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the lastly recorded polygon.
3467477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
346897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
346997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
347097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
347197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> p = turtle.get_poly()
347297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.register_shape("myFavouriteShape", p)
3473477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
3474eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        ## check if there is any poly?
347597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self._poly is not None:
347697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return tuple(self._poly)
3477fd2ede2aa84e77dac30e297a04fc49dd3bb61c68Guido van Rossum
347897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def getscreen(self):
347997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the TurtleScreen object, the turtle is drawing  on.
3480477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
348197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
3482fd2ede2aa84e77dac30e297a04fc49dd3bb61c68Guido van Rossum
348397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Return the TurtleScreen object, the turtle is drawing  on.
348497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        So TurtleScreen-methods can be called for that object.
3485477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
348697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
348797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> ts = turtle.getscreen()
348897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> ts
348997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        <turtle.TurtleScreen object at 0x0106B770>
349097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> ts.bgcolor("pink")
3491477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
349297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.screen
3493b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
349497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def getturtle(self):
349597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Return the Turtleobject itself.
3496477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
349797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
349897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
349997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Only reasonable use: as a function to return the 'anonymous turtle':
3500477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
3501477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        Example:
350297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> pet = getturtle()
350397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> pet.fd(50)
350497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> pet
350597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        <turtle.Turtle object at 0x0187D810>
350697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtles()
350797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        [<turtle.Turtle object at 0x0187D810>]
3508477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
350997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self
351097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
351197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    getpen = getturtle
351297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
351397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
351497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    ################################################################
351597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    ### screen oriented methods recurring to methods of TurtleScreen
351697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    ################################################################
351797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
351897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _delay(self, delay=None):
351997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set delay value which determines speed of turtle animation.
352097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
352197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return self.screen.delay(delay)
3522477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
352397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def onclick(self, fun, btn=1, add=None):
352497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-click event on this turtle on canvas.
3525477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
352697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
352797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun --  a function with two arguments, to which will be assigned
352897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                the coordinates of the clicked point on the canvas.
352997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num --  number of the mouse-button defaults to 1 (left mouse button).
353097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        add --  True or False. If True, new binding will be added, otherwise
353197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                it will replace a former binding.
3532477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
353397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example for the anonymous turtle, i. e. the procedural way:
3534477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
353597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> def turn(x, y):
35369aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     left(360)
35379aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...
35389aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        >>> onclick(turn)  # Now clicking into the turtle will turn it.
353997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> onclick(None)  # event-binding will be removed
3540477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
354197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screen._onclick(self.turtle._item, fun, btn, add)
354297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
354397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
354497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def onrelease(self, fun, btn=1, add=None):
354597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-button-release event on this turtle on canvas.
354697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
354797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
354897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun -- a function with two arguments, to which will be assigned
354997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                the coordinates of the clicked point on the canvas.
355097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num --  number of the mouse-button defaults to 1 (left mouse button).
355197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
355297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a MyTurtle instance named joe):
355397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> class MyTurtle(Turtle):
35549aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     def glow(self,x,y):
35559aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...             self.fillcolor("red")
35569aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     def unglow(self,x,y):
35579aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...             self.fillcolor("")
35589aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...
355997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> joe = MyTurtle()
356097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> joe.onclick(joe.glow)
356197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> joe.onrelease(joe.unglow)
35629aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen
35639aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        Clicking on joe turns fillcolor red, unclicking turns it to
35649aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        transparent.
356597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
356697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screen._onrelease(self.turtle._item, fun, btn, add)
356797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._update()
3568477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
356997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def ondrag(self, fun, btn=1, add=None):
357097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Bind fun to mouse-move event on this turtle on canvas.
3571477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
357297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
357397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fun -- a function with two arguments, to which will be assigned
357497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis               the coordinates of the clicked point on the canvas.
357597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        num -- number of the mouse-button defaults to 1 (left mouse button).
3576477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
357797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Every sequence of mouse-move-events on a turtle is preceded by a
357897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        mouse-click event on that turtle.
3579477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
358097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
358197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> turtle.ondrag(turtle.goto)
3582477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
35839aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        Subsequently clicking and dragging a Turtle will move it
35849aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        across the screen thereby producing handdrawings (if pen is
35859aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        down).
358697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
358797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.screen._ondrag(self.turtle._item, fun, btn, add)
3588477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
3589477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
359097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _undo(self, action, data):
359197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Does the main part of the work for undo()
3592477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        """
359397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer is None:
35943c7a25a4d9ea07f2aa8e4b70fecd84e33de82c2eGuido van Rossum            return
359597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if action == "rot":
359697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            angle, degPAU = data
359797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._rotate(-angle*degPAU/self._degreesPerAU)
359897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            dummy = self.undobuffer.pop()
359997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif action == "stamp":
360097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            stitem = data[0]
360197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.clearstamp(stitem)
360297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif action == "go":
360397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._undogoto(data)
360497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif action in ["wri", "dot"]:
360597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            item = data[0]
360697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen._delete(item)
360797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.items.remove(item)
360897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif action == "dofill":
360997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            item = data[0]
361097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.screen._drawpoly(item, ((0, 0),(0, 0),(0, 0)),
361197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                  fill="", outline="")
361297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif action == "beginfill":
361397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            item = data[0]
361497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._fillitem = self._fillpath = None
361597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if item in self.items:
361697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.screen._delete(item)
361797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self.items.remove(item)
361897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        elif action == "pen":
361997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            TPen.pen(self, data[0])
362097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.undobuffer.pop()
362197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
362297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def undo(self):
362397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """undo (repeatedly) the last turtle action.
362497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
362597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No argument.
362697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
362797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        undo (repeatedly) the last turtle action.
362897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Number of available undo actions is determined by the size of
362997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        the undobuffer.
363097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
363197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Turtle instance named turtle):
363297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> for i in range(4):
36339aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     turtle.fd(50); turtle.lt(80)
36349aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...
363597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> for i in range(8):
36369aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...     turtle.undo()
36379aa20affb6603a297f0327da7e990ba2e7e2daebPetri Lehtinen        ...
363897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
363997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if self.undobuffer is None:
364097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
364197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        item = self.undobuffer.pop()
364297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        action = item[0]
364397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        data = item[1:]
364497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if action == "seq":
364597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            while data:
364697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                item = data.pop()
364797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                self._undo(item[0], item[1:])
364897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
364997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._undo(action, data)
3650b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
365197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    turtlesize = shapesize
3652477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
365397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. LöwisRawPen = RawTurtle
3654477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
3655601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis###  Screen - Singleton  ########################
3656477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
3657601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwisdef Screen():
3658601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis    """Return the singleton screen object.
3659601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis    If none exists at the moment, create a new one and return it,
3660601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis    else return the existing one."""
3661601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis    if Turtle._screen is None:
3662601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        Turtle._screen = _Screen()
3663601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis    return Turtle._screen
3664601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis
3665601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwisclass _Screen(TurtleScreen):
3666b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum
366797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _root = None
366897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _canvas = None
366997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _title = _CFG["title"]
3670d038ca830fd5a6bafbd24b70eb71aeae83d362d3Fred Drake
367197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self):
3672601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        # XXX there is no need for this code to be conditional,
3673601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        # as there will be only a single _Screen instance, anyway
3674601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        # XXX actually, the turtle demo is injecting root window,
3675601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        # so perhaps the conditional creation of a root should be
3676601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        # preserved (perhaps by passing it as an optional parameter)
3677601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        if _Screen._root is None:
3678601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis            _Screen._root = self._root = _Root()
3679601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis            self._root.title(_Screen._title)
368097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._root.ondestroy(self._destroy)
3681601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        if _Screen._canvas is None:
368297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            width = _CFG["width"]
368397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            height = _CFG["height"]
368497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            canvwidth = _CFG["canvwidth"]
368597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            canvheight = _CFG["canvheight"]
368697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            leftright = _CFG["leftright"]
368797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            topbottom = _CFG["topbottom"]
368897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self._root.setupcanvas(width, height, canvwidth, canvheight)
3689601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis            _Screen._canvas = self._root._getcanvas()
3690601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis            TurtleScreen.__init__(self, _Screen._canvas)
3691eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl            self.setup(width, height, leftright, topbottom)
369297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
369397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def setup(self, width=_CFG["width"], height=_CFG["height"],
369497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis              startx=_CFG["leftright"], starty=_CFG["topbottom"]):
369597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """ Set the size and position of the main window.
369697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
369797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Arguments:
369897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        width: as integer a size in pixels, as float a fraction of the screen.
369997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          Default is 50% of screen.
370097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        height: as integer the height in pixels, as float a fraction of the
370197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          screen. Default is 75% of screen.
370297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        startx: if positive, starting position in pixels from the left
370397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          edge of the screen, if negative from the right edge
370497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          Default, startx=None is to center window horizontally.
370597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        starty: if positive, starting position in pixels from the top
370697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          edge of the screen, if negative from the bottom edge
370797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis          Default, starty=None is to center window vertically.
370897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
370997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Examples (for a Screen instance named screen):
371097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.setup (width=200, height=200, startx=0, starty=0)
371197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
371297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        sets window to 200x200 pixels, in upper left of screen
371397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
371497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.setup(width=.75, height=0.5, startx=None, starty=None)
371597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
371697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        sets window to 75% of screen by 50% of screen and centers
371797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
371897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if not hasattr(self._root, "set_geometry"):
371997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
372097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        sw = self._root.win_width()
372197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        sh = self._root.win_height()
372297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(width, float) and 0 <= width <= 1:
372397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            width = sw*width
372497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if startx is None:
372597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            startx = (sw - width) / 2
372697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isinstance(height, float) and 0 <= height <= 1:
372797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            height = sh*height
372897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if starty is None:
372997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            starty = (sh - height) / 2
373097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._root.set_geometry(width, height, startx, starty)
3731eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandl        self.update()
373297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
373397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def title(self, titlestring):
373497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Set title of turtle-window
373597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
373697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Argument:
373797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        titlestring -- a string, to appear in the titlebar of the
373897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                       turtle graphics window.
373997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
374097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        This is a method of Screen-class. Not available for TurtleScreen-
374197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        objects.
374297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
374397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Screen instance named screen):
374497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.title("Welcome to the turtle-zoo!")
374597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
3746601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        if _Screen._root is not None:
3747601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis            _Screen._root.title(titlestring)
3748601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        _Screen._title = titlestring
3749477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
375097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def _destroy(self):
375197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        root = self._root
3752601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        if root is _Screen._root:
375397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            Turtle._pen = None
375497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            Turtle._screen = None
3755601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis            _Screen._root = None
3756601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis            _Screen._canvas = None
375780a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka        TurtleScreen._RUNNING = False
375897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        root.destroy()
3759477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
376097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def bye(self):
376197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Shut the turtlegraphics window.
3762477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
376397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a TurtleScreen instance named screen):
376497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.bye()
376597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
376697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self._destroy()
3767477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
376897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def exitonclick(self):
376997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Go into mainloop until the mouse is clicked.
3770477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
377197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        No arguments.
3772477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
377397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Bind bye() method to mouseclick on TurtleScreen.
377497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If "using_IDLE" - value in configuration dictionary is False
377597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        (default value), enter mainloop.
377697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        If IDLE with -n switch (no subprocess) is used, this value should be
377797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        set to True in turtle.cfg. In this case IDLE's mainloop
377897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        is active also for the client script.
3779477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
378097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        This is a method of the Screen-class and not available for
378197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        TurtleScreen instances.
3782477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
378397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        Example (for a Screen instance named screen):
378497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        >>> screen.exitonclick()
3785477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
378697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """
378797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        def exitGracefully(x, y):
378897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            """Screen.bye() with two dummy-parameters"""
378997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            self.bye()
379097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        self.onclick(exitGracefully)
379197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if _CFG["using_IDLE"]:
379297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            return
379397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        try:
379497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            mainloop()
379597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        except AttributeError:
379697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            exit(0)
3797477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
379897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisclass Turtle(RawTurtle):
379913925008dc11f2a235627dc8c0440c0ce99171d9Ezio Melotti    """RawTurtle auto-creating (scrolled) canvas.
3800477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
380197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    When a Turtle object is created or a function derived from some
380297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Turtle method is called a TurtleScreen object is automatically created.
380397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
380497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _pen = None
380597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    _screen = None
380697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
380797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def __init__(self,
380897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 shape=_CFG["shape"],
380997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 undobuffersize=_CFG["undobuffersize"],
381097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                 visible=_CFG["visible"]):
381197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if Turtle._screen is None:
381297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            Turtle._screen = Screen()
381397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        RawTurtle.__init__(self, Turtle._screen,
381497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                           shape=shape,
381597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                           undobuffersize=undobuffersize,
381697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                           visible=visible)
381797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
381897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. LöwisPen = Turtle
3819477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
382097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef write_docstringdict(filename="turtle_docstringdict"):
382197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Create and write docstring-dictionary to file.
382297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
382397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Optional argument:
382497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    filename -- a string, used as filename
382597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                default value is turtle_docstringdict
382697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
382713925008dc11f2a235627dc8c0440c0ce99171d9Ezio Melotti    Has to be called explicitly, (not used by the turtle-graphics classes)
382897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    The docstring dictionary will be written to the Python script <filname>.py
382997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    It is intended to serve as a template for translation of the docstrings
383097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    into different languages.
383197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
383297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    docsdict = {}
383397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
383497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for methodname in _tg_screen_functions:
3835601149bb8e4fd200cc5b0b670f34c608c64e0783Martin v. Löwis        key = "_Screen."+methodname
383697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        docsdict[key] = eval(key).__doc__
383797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for methodname in _tg_turtle_functions:
383897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        key = "Turtle."+methodname
383997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        docsdict[key] = eval(key).__doc__
384097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
38412f50aaf2ff427fb713e82699a6dcbeeb038b10c2Giampaolo Rodola'    with open("%s.py" % filename,"w") as f:
38422f50aaf2ff427fb713e82699a6dcbeeb038b10c2Giampaolo Rodola'        keys = sorted([x for x in docsdict.keys()
38432f50aaf2ff427fb713e82699a6dcbeeb038b10c2Giampaolo Rodola'                            if x.split('.')[1] not in _alias_list])
38442f50aaf2ff427fb713e82699a6dcbeeb038b10c2Giampaolo Rodola'        f.write('docsdict = {\n\n')
38452f50aaf2ff427fb713e82699a6dcbeeb038b10c2Giampaolo Rodola'        for key in keys[:-1]:
38462f50aaf2ff427fb713e82699a6dcbeeb038b10c2Giampaolo Rodola'            f.write('%s :\n' % repr(key))
38472f50aaf2ff427fb713e82699a6dcbeeb038b10c2Giampaolo Rodola'            f.write('        """%s\n""",\n\n' % docsdict[key])
38482f50aaf2ff427fb713e82699a6dcbeeb038b10c2Giampaolo Rodola'        key = keys[-1]
384997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        f.write('%s :\n' % repr(key))
38502f50aaf2ff427fb713e82699a6dcbeeb038b10c2Giampaolo Rodola'        f.write('        """%s\n"""\n\n' % docsdict[key])
38512f50aaf2ff427fb713e82699a6dcbeeb038b10c2Giampaolo Rodola'        f.write("}\n")
38522f50aaf2ff427fb713e82699a6dcbeeb038b10c2Giampaolo Rodola'        f.close()
385397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
385497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef read_docstrings(lang):
385597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """Read in docstrings from lang-specific docstring dictionary.
385697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
385797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    Transfer docstrings, translated to lang, from a dictionary-file
385897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    to the methods of classes Screen and Turtle and - in revised form -
385997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    to the corresponding functions.
386097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
386197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    modname = "turtle_docstringdict_%(language)s" % {'language':lang.lower()}
386297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    module = __import__(modname)
386397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    docsdict = module.docsdict
386497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    for key in docsdict:
386597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        try:
386697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis#            eval(key).im_func.__doc__ = docsdict[key]
386797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            eval(key).__doc__ = docsdict[key]
3868cefa9172a237a56c67e8c9b302c84c1c3dffb871Serhiy Storchaka        except Exception:
386997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            print("Bad docstring-entry: %s" % key)
387097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
387197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis_LANGUAGE = _CFG["language"]
387297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
387397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwistry:
387497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if _LANGUAGE != "english":
387597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        read_docstrings(_LANGUAGE)
387697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisexcept ImportError:
387797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    print("Cannot find docsdict for", _LANGUAGE)
3878cefa9172a237a56c67e8c9b302c84c1c3dffb871Serhiy Storchakaexcept Exception:
387997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    print ("Unknown Error when trying to import %s-docstring-dictionary" %
388097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                                                                  _LANGUAGE)
388197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
388297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
388397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef getmethparlist(ob):
3884c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    """Get strings describing the arguments for the given object
3885c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky
3886c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    Returns a pair of strings representing function parameter lists
3887c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    including parenthesis.  The first string is suitable for use in
3888c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    function definition and the second is suitable for use in function
3889c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    call.  The "self" parameter is not included.
3890c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    """
3891c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    defText = callText = ""
389297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    # bit of a hack for methods - turn it into a function
389397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    # but we drop the "self" param.
389497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    # Try and build one for Python defined functions
3895c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    args, varargs, varkw = inspect.getargs(ob.__code__)
3896c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    items2 = args[1:]
3897c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    realArgs = args[1:]
389897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    defaults = ob.__defaults__ or []
3899c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    defaults = ["=%r" % (value,) for value in defaults]
390097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    defaults = [""] * (len(realArgs)-len(defaults)) + defaults
3901c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    items1 = [arg + dflt for arg, dflt in zip(realArgs, defaults)]
3902c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    if varargs is not None:
3903c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky        items1.append("*" + varargs)
3904c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky        items2.append("*" + varargs)
3905c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    if varkw is not None:
3906c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky        items1.append("**" + varkw)
3907c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky        items2.append("**" + varkw)
3908c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    defText = ", ".join(items1)
3909c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    defText = "(%s)" % defText
3910c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    callText = ", ".join(items2)
3911c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    callText = "(%s)" % callText
3912c1a68363057b7b939fccbe35ab5f9d288e0ef6c1Alexander Belopolsky    return defText, callText
391397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
391497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef _turtle_docrevise(docstr):
391597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """To reduce docstrings from RawTurtle class for functions
3916477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    """
391797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    import re
391897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if docstr is None:
391997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return None
392097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    turtlename = _CFG["exampleturtle"]
392197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    newdocstr = docstr.replace("%s." % turtlename,"")
392297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    parexp = re.compile(r' \(.+ %s\):' % turtlename)
392397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    newdocstr = parexp.sub(":", newdocstr)
392497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    return newdocstr
392597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
392697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisdef _screen_docrevise(docstr):
392797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """To reduce docstrings from TurtleScreen class for functions
392897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    """
392997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    import re
393097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    if docstr is None:
393197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        return None
393297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    screenname = _CFG["examplescreen"]
393397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    newdocstr = docstr.replace("%s." % screenname,"")
393497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    parexp = re.compile(r' \(.+ %s\):' % screenname)
393597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    newdocstr = parexp.sub(":", newdocstr)
393697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    return newdocstr
393797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
393897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis## The following mechanism makes all methods of RawTurtle and Turtle available
393997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis## as functions. So we can enhance, change, add, delete methods to these
394097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis## classes and do not need to change anything here.
394197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
394280a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka__func_body = """\
394380a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchakadef {name}{paramslist}:
394480a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka    if {obj} is None:
394580a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka        if not TurtleScreen._RUNNING:
394680a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka            TurtleScreen._RUNNING = True
394780a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka            raise Terminator
394880a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka        {obj} = {init}
394980a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka    try:
395080a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka        return {obj}.{name}{argslist}
395180a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka    except TK.TclError:
395280a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka        if not TurtleScreen._RUNNING:
395380a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka            TurtleScreen._RUNNING = True
395480a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka            raise Terminator
395580a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka        raise
395680a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka"""
395797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
395880a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchakadef _make_global_funcs(functions, cls, obj, init, docrevise):
395980a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka    for methodname in functions:
396080a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka        method = getattr(cls, methodname)
396180a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka        pl1, pl2 = getmethparlist(method)
396280a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka        if pl1 == "":
396380a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka            print(">>>>>>", pl1, pl2)
396480a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka            continue
396580a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka        defstr = __func_body.format(obj=obj, init=init, name=methodname,
396680a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka                                    paramslist=pl1, argslist=pl2)
396780a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka        exec(defstr, globals())
396880a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka        globals()[methodname].__doc__ = docrevise(method.__doc__)
396980a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka
397080a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka_make_global_funcs(_tg_screen_functions, _Screen,
397180a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka                   'Turtle._screen', 'Screen()', _screen_docrevise)
397280a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka_make_global_funcs(_tg_turtle_functions, Turtle,
397380a1803193bcaef7a50324974117c3aa3fb0e48fSerhiy Storchaka                   'Turtle._pen', 'Turtle()', _turtle_docrevise)
397497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
397597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
3976eaa84ef1e96f1f597ef54f40147de2e6a6980e34Georg Brandldone = mainloop
397797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
397897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwisif __name__ == "__main__":
397997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def switchpen():
398097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        if isdown():
398197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pu()
398297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        else:
398397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            pd()
3984477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters
398597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def demo1():
398697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Demo of old turtle.py - module"""
398797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        reset()
398897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tracer(True)
3989b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum        up()
399097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        backward(100)
3991b241b67b8954b0679377af00d668e3dc92f4c858Guido van Rossum        down()
399297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # draw 3 squares; the last filled
399397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        width(3)
399497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for i in range(3):
399597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if i == 2:
399697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                begin_fill()
399797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for _ in range(4):
399897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                forward(20)
399997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                left(90)
400097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if i == 2:
400197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                color("maroon")
400297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                end_fill()
4003477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters            up()
400497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            forward(30)
4005477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters            down()
400697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        width(1)
400797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color("black")
400897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # move out of the way
400997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tracer(False)
401097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        up()
40110e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters        right(90)
401297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        forward(100)
40130e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters        right(90)
401497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        forward(100)
401597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        right(180)
401697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        down()
401797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # some text
401897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        write("startstart", 1)
401997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        write("start", 1)
402097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color("red")
402197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # staircase
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        # filled staircase
402897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tracer(True)
402997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        begin_fill()
403097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for i in range(5):
403197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            forward(20)
403297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            left(90)
403397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            forward(20)
403497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            right(90)
403597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        end_fill()
403697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        # more text
403797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
403897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    def demo2():
403997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        """Demo of some new features."""
404097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speed(1)
404197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        st()
404297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pensize(3)
404397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        setheading(towards(0, 0))
404497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        radius = distance(0, 0)/2.0
404597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        rt(90)
404697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for _ in range(18):
404797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            switchpen()
404897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            circle(radius, 10)
404997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        write("wait a moment...")
405097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        while undobufferentries():
405197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            undo()
405297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        reset()
405397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        lt(90)
405497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        colormode(255)
405597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        laenge = 10
405697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pencolor("green")
405797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pensize(3)
405897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        lt(180)
405997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for i in range(-2, 16):
406097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if i > 0:
406197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                begin_fill()
406297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fillcolor(255-15*i, 0, 15*i)
406397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            for _ in range(3):
406497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                fd(laenge)
406597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                lt(120)
406697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            end_fill()
406797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            laenge += 10
406897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            lt(15)
406997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            speed((speed()+1)%12)
407097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        #end_fill()
407197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
407297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        lt(120)
407397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pu()
407497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fd(70)
407597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        rt(30)
407697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pd()
407797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        color("red","yellow")
407897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        speed(0)
407997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        begin_fill()
408097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        for _ in range(4):
408197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            circle(50, 90)
408297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            rt(90)
408397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            fd(30)
408497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            rt(90)
408597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        end_fill()
408697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        lt(90)
408797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pu()
408897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        fd(30)
408997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        pd()
409097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        shape("turtle")
409197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
409297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri = getturtle()
409397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.resizemode("auto")
409497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle = Turtle()
409597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.resizemode("auto")
409697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.shape("turtle")
409797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.reset()
409897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.left(90)
409997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.speed(0)
410097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.up()
410197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.goto(280, 40)
410297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.lt(30)
410397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.down()
410497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.speed(6)
410597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.color("blue","orange")
410697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        turtle.pensize(2)
410797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.speed(6)
4108477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters        setheading(towards(turtle))
410997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        count = 1
411097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        while tri.distance(turtle) > 4:
411197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            turtle.fd(3.5)
411297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            turtle.lt(0.6)
411397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            tri.setheading(tri.towards(turtle))
411497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            tri.fd(4)
411597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            if count % 20 == 0:
411697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                turtle.stamp()
411797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                tri.stamp()
411897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis                switchpen()
411997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            count += 1
412097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.write("CAUGHT! ", font=("Arial", 16, "bold"), align="right")
412197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.pencolor("black")
412297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.pencolor("red")
412397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
412497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        def baba(xdummy, ydummy):
412597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            clearscreen()
412697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            bye()
412797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
412897cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        time.sleep(2)
412997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
413097cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        while undobufferentries():
413197cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            tri.undo()
413297cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis            turtle.undo()
413397cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.fd(50)
413497cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.write("  Click me!", font = ("Courier", 12, "bold") )
413597cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis        tri.onclick(baba, 1)
413697cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis
413797cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    demo1()
4138477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters    demo2()
413997cf99fc7e8c56868711f7c91c3b1e37e4c66cbaMartin v. Löwis    exitonclick()
4140