1*cda5da8dSAndroid Build Coastguard Worker# 2*cda5da8dSAndroid Build Coastguard Worker# turtle.py: a Tkinter based turtle graphics module for Python 3*cda5da8dSAndroid Build Coastguard Worker# Version 1.1b - 4. 5. 2009 4*cda5da8dSAndroid Build Coastguard Worker# 5*cda5da8dSAndroid Build Coastguard Worker# Copyright (C) 2006 - 2010 Gregor Lingl 6*cda5da8dSAndroid Build Coastguard Worker# email: [email protected] 7*cda5da8dSAndroid Build Coastguard Worker# 8*cda5da8dSAndroid Build Coastguard Worker# This software is provided 'as-is', without any express or implied 9*cda5da8dSAndroid Build Coastguard Worker# warranty. In no event will the authors be held liable for any damages 10*cda5da8dSAndroid Build Coastguard Worker# arising from the use of this software. 11*cda5da8dSAndroid Build Coastguard Worker# 12*cda5da8dSAndroid Build Coastguard Worker# Permission is granted to anyone to use this software for any purpose, 13*cda5da8dSAndroid Build Coastguard Worker# including commercial applications, and to alter it and redistribute it 14*cda5da8dSAndroid Build Coastguard Worker# freely, subject to the following restrictions: 15*cda5da8dSAndroid Build Coastguard Worker# 16*cda5da8dSAndroid Build Coastguard Worker# 1. The origin of this software must not be misrepresented; you must not 17*cda5da8dSAndroid Build Coastguard Worker# claim that you wrote the original software. If you use this software 18*cda5da8dSAndroid Build Coastguard Worker# in a product, an acknowledgment in the product documentation would be 19*cda5da8dSAndroid Build Coastguard Worker# appreciated but is not required. 20*cda5da8dSAndroid Build Coastguard Worker# 2. Altered source versions must be plainly marked as such, and must not be 21*cda5da8dSAndroid Build Coastguard Worker# misrepresented as being the original software. 22*cda5da8dSAndroid Build Coastguard Worker# 3. This notice may not be removed or altered from any source distribution. 23*cda5da8dSAndroid Build Coastguard Worker 24*cda5da8dSAndroid Build Coastguard Worker 25*cda5da8dSAndroid Build Coastguard Worker""" 26*cda5da8dSAndroid Build Coastguard WorkerTurtle graphics is a popular way for introducing programming to 27*cda5da8dSAndroid Build Coastguard Workerkids. It was part of the original Logo programming language developed 28*cda5da8dSAndroid Build Coastguard Workerby Wally Feurzig and Seymour Papert in 1966. 29*cda5da8dSAndroid Build Coastguard Worker 30*cda5da8dSAndroid Build Coastguard WorkerImagine a robotic turtle starting at (0, 0) in the x-y plane. After an ``import turtle``, give it 31*cda5da8dSAndroid Build Coastguard Workerthe command turtle.forward(15), and it moves (on-screen!) 15 pixels in 32*cda5da8dSAndroid Build Coastguard Workerthe direction it is facing, drawing a line as it moves. Give it the 33*cda5da8dSAndroid Build Coastguard Workercommand turtle.right(25), and it rotates in-place 25 degrees clockwise. 34*cda5da8dSAndroid Build Coastguard Worker 35*cda5da8dSAndroid Build Coastguard WorkerBy combining together these and similar commands, intricate shapes and 36*cda5da8dSAndroid Build Coastguard Workerpictures can easily be drawn. 37*cda5da8dSAndroid Build Coastguard Worker 38*cda5da8dSAndroid Build Coastguard Worker----- turtle.py 39*cda5da8dSAndroid Build Coastguard Worker 40*cda5da8dSAndroid Build Coastguard WorkerThis module is an extended reimplementation of turtle.py from the 41*cda5da8dSAndroid Build Coastguard WorkerPython standard distribution up to Python 2.5. (See: https://www.python.org) 42*cda5da8dSAndroid Build Coastguard Worker 43*cda5da8dSAndroid Build Coastguard WorkerIt tries to keep the merits of turtle.py and to be (nearly) 100% 44*cda5da8dSAndroid Build Coastguard Workercompatible with it. This means in the first place to enable the 45*cda5da8dSAndroid Build Coastguard Workerlearning programmer to use all the commands, classes and methods 46*cda5da8dSAndroid Build Coastguard Workerinteractively when using the module from within IDLE run with 47*cda5da8dSAndroid Build Coastguard Workerthe -n switch. 48*cda5da8dSAndroid Build Coastguard Worker 49*cda5da8dSAndroid Build Coastguard WorkerRoughly it has the following features added: 50*cda5da8dSAndroid Build Coastguard Worker 51*cda5da8dSAndroid Build Coastguard Worker- Better animation of the turtle movements, especially of turning the 52*cda5da8dSAndroid Build Coastguard Worker turtle. So the turtles can more easily be used as a visual feedback 53*cda5da8dSAndroid Build Coastguard Worker instrument by the (beginning) programmer. 54*cda5da8dSAndroid Build Coastguard Worker 55*cda5da8dSAndroid Build Coastguard Worker- Different turtle shapes, gif-images as turtle shapes, user defined 56*cda5da8dSAndroid Build Coastguard Worker and user controllable turtle shapes, among them compound 57*cda5da8dSAndroid Build Coastguard Worker (multicolored) shapes. Turtle shapes can be stretched and tilted, which 58*cda5da8dSAndroid Build Coastguard Worker makes turtles very versatile geometrical objects. 59*cda5da8dSAndroid Build Coastguard Worker 60*cda5da8dSAndroid Build Coastguard Worker- Fine control over turtle movement and screen updates via delay(), 61*cda5da8dSAndroid Build Coastguard Worker and enhanced tracer() and speed() methods. 62*cda5da8dSAndroid Build Coastguard Worker 63*cda5da8dSAndroid Build Coastguard Worker- Aliases for the most commonly used commands, like fd for forward etc., 64*cda5da8dSAndroid Build Coastguard Worker following the early Logo traditions. This reduces the boring work of 65*cda5da8dSAndroid Build Coastguard Worker typing long sequences of commands, which often occur in a natural way 66*cda5da8dSAndroid Build Coastguard Worker when kids try to program fancy pictures on their first encounter with 67*cda5da8dSAndroid Build Coastguard Worker turtle graphics. 68*cda5da8dSAndroid Build Coastguard Worker 69*cda5da8dSAndroid Build Coastguard Worker- Turtles now have an undo()-method with configurable undo-buffer. 70*cda5da8dSAndroid Build Coastguard Worker 71*cda5da8dSAndroid Build Coastguard Worker- Some simple commands/methods for creating event driven programs 72*cda5da8dSAndroid Build Coastguard Worker (mouse-, key-, timer-events). Especially useful for programming games. 73*cda5da8dSAndroid Build Coastguard Worker 74*cda5da8dSAndroid Build Coastguard Worker- A scrollable Canvas class. The default scrollable Canvas can be 75*cda5da8dSAndroid Build Coastguard Worker extended interactively as needed while playing around with the turtle(s). 76*cda5da8dSAndroid Build Coastguard Worker 77*cda5da8dSAndroid Build Coastguard Worker- A TurtleScreen class with methods controlling background color or 78*cda5da8dSAndroid Build Coastguard Worker background image, window and canvas size and other properties of the 79*cda5da8dSAndroid Build Coastguard Worker TurtleScreen. 80*cda5da8dSAndroid Build Coastguard Worker 81*cda5da8dSAndroid Build Coastguard Worker- There is a method, setworldcoordinates(), to install a user defined 82*cda5da8dSAndroid Build Coastguard Worker coordinate-system for the TurtleScreen. 83*cda5da8dSAndroid Build Coastguard Worker 84*cda5da8dSAndroid Build Coastguard Worker- The implementation uses a 2-vector class named Vec2D, derived from tuple. 85*cda5da8dSAndroid Build Coastguard Worker This class is public, so it can be imported by the application programmer, 86*cda5da8dSAndroid Build Coastguard Worker which makes certain types of computations very natural and compact. 87*cda5da8dSAndroid Build Coastguard Worker 88*cda5da8dSAndroid Build Coastguard Worker- Appearance of the TurtleScreen and the Turtles at startup/import can be 89*cda5da8dSAndroid Build Coastguard Worker configured by means of a turtle.cfg configuration file. 90*cda5da8dSAndroid Build Coastguard Worker The default configuration mimics the appearance of the old turtle module. 91*cda5da8dSAndroid Build Coastguard Worker 92*cda5da8dSAndroid Build Coastguard Worker- If configured appropriately the module reads in docstrings from a docstring 93*cda5da8dSAndroid Build Coastguard Worker dictionary in some different language, supplied separately and replaces 94*cda5da8dSAndroid Build Coastguard Worker the English ones by those read in. There is a utility function 95*cda5da8dSAndroid Build Coastguard Worker write_docstringdict() to write a dictionary with the original (English) 96*cda5da8dSAndroid Build Coastguard Worker docstrings to disc, so it can serve as a template for translations. 97*cda5da8dSAndroid Build Coastguard Worker 98*cda5da8dSAndroid Build Coastguard WorkerBehind the scenes there are some features included with possible 99*cda5da8dSAndroid Build Coastguard Workerextensions in mind. These will be commented and documented elsewhere. 100*cda5da8dSAndroid Build Coastguard Worker 101*cda5da8dSAndroid Build Coastguard Worker""" 102*cda5da8dSAndroid Build Coastguard Worker 103*cda5da8dSAndroid Build Coastguard Worker_ver = "turtle 1.1b- - for Python 3.1 - 4. 5. 2009" 104*cda5da8dSAndroid Build Coastguard Worker 105*cda5da8dSAndroid Build Coastguard Worker# print(_ver) 106*cda5da8dSAndroid Build Coastguard Worker 107*cda5da8dSAndroid Build Coastguard Workerimport tkinter as TK 108*cda5da8dSAndroid Build Coastguard Workerimport types 109*cda5da8dSAndroid Build Coastguard Workerimport math 110*cda5da8dSAndroid Build Coastguard Workerimport time 111*cda5da8dSAndroid Build Coastguard Workerimport inspect 112*cda5da8dSAndroid Build Coastguard Workerimport sys 113*cda5da8dSAndroid Build Coastguard Workerimport warnings 114*cda5da8dSAndroid Build Coastguard Worker 115*cda5da8dSAndroid Build Coastguard Workerfrom os.path import isfile, split, join 116*cda5da8dSAndroid Build Coastguard Workerfrom copy import deepcopy 117*cda5da8dSAndroid Build Coastguard Workerfrom tkinter import simpledialog 118*cda5da8dSAndroid Build Coastguard Worker 119*cda5da8dSAndroid Build Coastguard Worker_tg_classes = ['ScrolledCanvas', 'TurtleScreen', 'Screen', 120*cda5da8dSAndroid Build Coastguard Worker 'RawTurtle', 'Turtle', 'RawPen', 'Pen', 'Shape', 'Vec2D'] 121*cda5da8dSAndroid Build Coastguard Worker_tg_screen_functions = ['addshape', 'bgcolor', 'bgpic', 'bye', 122*cda5da8dSAndroid Build Coastguard Worker 'clearscreen', 'colormode', 'delay', 'exitonclick', 'getcanvas', 123*cda5da8dSAndroid Build Coastguard Worker 'getshapes', 'listen', 'mainloop', 'mode', 'numinput', 124*cda5da8dSAndroid Build Coastguard Worker 'onkey', 'onkeypress', 'onkeyrelease', 'onscreenclick', 'ontimer', 125*cda5da8dSAndroid Build Coastguard Worker 'register_shape', 'resetscreen', 'screensize', 'setup', 126*cda5da8dSAndroid Build Coastguard Worker 'setworldcoordinates', 'textinput', 'title', 'tracer', 'turtles', 'update', 127*cda5da8dSAndroid Build Coastguard Worker 'window_height', 'window_width'] 128*cda5da8dSAndroid Build Coastguard Worker_tg_turtle_functions = ['back', 'backward', 'begin_fill', 'begin_poly', 'bk', 129*cda5da8dSAndroid Build Coastguard Worker 'circle', 'clear', 'clearstamp', 'clearstamps', 'clone', 'color', 130*cda5da8dSAndroid Build Coastguard Worker 'degrees', 'distance', 'dot', 'down', 'end_fill', 'end_poly', 'fd', 131*cda5da8dSAndroid Build Coastguard Worker 'fillcolor', 'filling', 'forward', 'get_poly', 'getpen', 'getscreen', 'get_shapepoly', 132*cda5da8dSAndroid Build Coastguard Worker 'getturtle', 'goto', 'heading', 'hideturtle', 'home', 'ht', 'isdown', 133*cda5da8dSAndroid Build Coastguard Worker 'isvisible', 'left', 'lt', 'onclick', 'ondrag', 'onrelease', 'pd', 134*cda5da8dSAndroid Build Coastguard Worker 'pen', 'pencolor', 'pendown', 'pensize', 'penup', 'pos', 'position', 135*cda5da8dSAndroid Build Coastguard Worker 'pu', 'radians', 'right', 'reset', 'resizemode', 'rt', 136*cda5da8dSAndroid Build Coastguard Worker 'seth', 'setheading', 'setpos', 'setposition', 'settiltangle', 137*cda5da8dSAndroid Build Coastguard Worker 'setundobuffer', 'setx', 'sety', 'shape', 'shapesize', 'shapetransform', 'shearfactor', 'showturtle', 138*cda5da8dSAndroid Build Coastguard Worker 'speed', 'st', 'stamp', 'tilt', 'tiltangle', 'towards', 139*cda5da8dSAndroid Build Coastguard Worker 'turtlesize', 'undo', 'undobufferentries', 'up', 'width', 140*cda5da8dSAndroid Build Coastguard Worker 'write', 'xcor', 'ycor'] 141*cda5da8dSAndroid Build Coastguard Worker_tg_utilities = ['write_docstringdict', 'done'] 142*cda5da8dSAndroid Build Coastguard Worker 143*cda5da8dSAndroid Build Coastguard Worker__all__ = (_tg_classes + _tg_screen_functions + _tg_turtle_functions + 144*cda5da8dSAndroid Build Coastguard Worker _tg_utilities + ['Terminator']) # + _math_functions) 145*cda5da8dSAndroid Build Coastguard Worker 146*cda5da8dSAndroid Build Coastguard Worker_alias_list = ['addshape', 'backward', 'bk', 'fd', 'ht', 'lt', 'pd', 'pos', 147*cda5da8dSAndroid Build Coastguard Worker 'pu', 'rt', 'seth', 'setpos', 'setposition', 'st', 148*cda5da8dSAndroid Build Coastguard Worker 'turtlesize', 'up', 'width'] 149*cda5da8dSAndroid Build Coastguard Worker 150*cda5da8dSAndroid Build Coastguard Worker_CFG = {"width" : 0.5, # Screen 151*cda5da8dSAndroid Build Coastguard Worker "height" : 0.75, 152*cda5da8dSAndroid Build Coastguard Worker "canvwidth" : 400, 153*cda5da8dSAndroid Build Coastguard Worker "canvheight": 300, 154*cda5da8dSAndroid Build Coastguard Worker "leftright": None, 155*cda5da8dSAndroid Build Coastguard Worker "topbottom": None, 156*cda5da8dSAndroid Build Coastguard Worker "mode": "standard", # TurtleScreen 157*cda5da8dSAndroid Build Coastguard Worker "colormode": 1.0, 158*cda5da8dSAndroid Build Coastguard Worker "delay": 10, 159*cda5da8dSAndroid Build Coastguard Worker "undobuffersize": 1000, # RawTurtle 160*cda5da8dSAndroid Build Coastguard Worker "shape": "classic", 161*cda5da8dSAndroid Build Coastguard Worker "pencolor" : "black", 162*cda5da8dSAndroid Build Coastguard Worker "fillcolor" : "black", 163*cda5da8dSAndroid Build Coastguard Worker "resizemode" : "noresize", 164*cda5da8dSAndroid Build Coastguard Worker "visible" : True, 165*cda5da8dSAndroid Build Coastguard Worker "language": "english", # docstrings 166*cda5da8dSAndroid Build Coastguard Worker "exampleturtle": "turtle", 167*cda5da8dSAndroid Build Coastguard Worker "examplescreen": "screen", 168*cda5da8dSAndroid Build Coastguard Worker "title": "Python Turtle Graphics", 169*cda5da8dSAndroid Build Coastguard Worker "using_IDLE": False 170*cda5da8dSAndroid Build Coastguard Worker } 171*cda5da8dSAndroid Build Coastguard Worker 172*cda5da8dSAndroid Build Coastguard Workerdef config_dict(filename): 173*cda5da8dSAndroid Build Coastguard Worker """Convert content of config-file into dictionary.""" 174*cda5da8dSAndroid Build Coastguard Worker with open(filename, "r") as f: 175*cda5da8dSAndroid Build Coastguard Worker cfglines = f.readlines() 176*cda5da8dSAndroid Build Coastguard Worker cfgdict = {} 177*cda5da8dSAndroid Build Coastguard Worker for line in cfglines: 178*cda5da8dSAndroid Build Coastguard Worker line = line.strip() 179*cda5da8dSAndroid Build Coastguard Worker if not line or line.startswith("#"): 180*cda5da8dSAndroid Build Coastguard Worker continue 181*cda5da8dSAndroid Build Coastguard Worker try: 182*cda5da8dSAndroid Build Coastguard Worker key, value = line.split("=") 183*cda5da8dSAndroid Build Coastguard Worker except ValueError: 184*cda5da8dSAndroid Build Coastguard Worker print("Bad line in config-file %s:\n%s" % (filename,line)) 185*cda5da8dSAndroid Build Coastguard Worker continue 186*cda5da8dSAndroid Build Coastguard Worker key = key.strip() 187*cda5da8dSAndroid Build Coastguard Worker value = value.strip() 188*cda5da8dSAndroid Build Coastguard Worker if value in ["True", "False", "None", "''", '""']: 189*cda5da8dSAndroid Build Coastguard Worker value = eval(value) 190*cda5da8dSAndroid Build Coastguard Worker else: 191*cda5da8dSAndroid Build Coastguard Worker try: 192*cda5da8dSAndroid Build Coastguard Worker if "." in value: 193*cda5da8dSAndroid Build Coastguard Worker value = float(value) 194*cda5da8dSAndroid Build Coastguard Worker else: 195*cda5da8dSAndroid Build Coastguard Worker value = int(value) 196*cda5da8dSAndroid Build Coastguard Worker except ValueError: 197*cda5da8dSAndroid Build Coastguard Worker pass # value need not be converted 198*cda5da8dSAndroid Build Coastguard Worker cfgdict[key] = value 199*cda5da8dSAndroid Build Coastguard Worker return cfgdict 200*cda5da8dSAndroid Build Coastguard Worker 201*cda5da8dSAndroid Build Coastguard Workerdef readconfig(cfgdict): 202*cda5da8dSAndroid Build Coastguard Worker """Read config-files, change configuration-dict accordingly. 203*cda5da8dSAndroid Build Coastguard Worker 204*cda5da8dSAndroid Build Coastguard Worker If there is a turtle.cfg file in the current working directory, 205*cda5da8dSAndroid Build Coastguard Worker read it from there. If this contains an importconfig-value, 206*cda5da8dSAndroid Build Coastguard Worker say 'myway', construct filename turtle_mayway.cfg else use 207*cda5da8dSAndroid Build Coastguard Worker turtle.cfg and read it from the import-directory, where 208*cda5da8dSAndroid Build Coastguard Worker turtle.py is located. 209*cda5da8dSAndroid Build Coastguard Worker Update configuration dictionary first according to config-file, 210*cda5da8dSAndroid Build Coastguard Worker in the import directory, then according to config-file in the 211*cda5da8dSAndroid Build Coastguard Worker current working directory. 212*cda5da8dSAndroid Build Coastguard Worker If no config-file is found, the default configuration is used. 213*cda5da8dSAndroid Build Coastguard Worker """ 214*cda5da8dSAndroid Build Coastguard Worker default_cfg = "turtle.cfg" 215*cda5da8dSAndroid Build Coastguard Worker cfgdict1 = {} 216*cda5da8dSAndroid Build Coastguard Worker cfgdict2 = {} 217*cda5da8dSAndroid Build Coastguard Worker if isfile(default_cfg): 218*cda5da8dSAndroid Build Coastguard Worker cfgdict1 = config_dict(default_cfg) 219*cda5da8dSAndroid Build Coastguard Worker if "importconfig" in cfgdict1: 220*cda5da8dSAndroid Build Coastguard Worker default_cfg = "turtle_%s.cfg" % cfgdict1["importconfig"] 221*cda5da8dSAndroid Build Coastguard Worker try: 222*cda5da8dSAndroid Build Coastguard Worker head, tail = split(__file__) 223*cda5da8dSAndroid Build Coastguard Worker cfg_file2 = join(head, default_cfg) 224*cda5da8dSAndroid Build Coastguard Worker except Exception: 225*cda5da8dSAndroid Build Coastguard Worker cfg_file2 = "" 226*cda5da8dSAndroid Build Coastguard Worker if isfile(cfg_file2): 227*cda5da8dSAndroid Build Coastguard Worker cfgdict2 = config_dict(cfg_file2) 228*cda5da8dSAndroid Build Coastguard Worker _CFG.update(cfgdict2) 229*cda5da8dSAndroid Build Coastguard Worker _CFG.update(cfgdict1) 230*cda5da8dSAndroid Build Coastguard Worker 231*cda5da8dSAndroid Build Coastguard Workertry: 232*cda5da8dSAndroid Build Coastguard Worker readconfig(_CFG) 233*cda5da8dSAndroid Build Coastguard Workerexcept Exception: 234*cda5da8dSAndroid Build Coastguard Worker print ("No configfile read, reason unknown") 235*cda5da8dSAndroid Build Coastguard Worker 236*cda5da8dSAndroid Build Coastguard Worker 237*cda5da8dSAndroid Build Coastguard Workerclass Vec2D(tuple): 238*cda5da8dSAndroid Build Coastguard Worker """A 2 dimensional vector class, used as a helper class 239*cda5da8dSAndroid Build Coastguard Worker for implementing turtle graphics. 240*cda5da8dSAndroid Build Coastguard Worker May be useful for turtle graphics programs also. 241*cda5da8dSAndroid Build Coastguard Worker Derived from tuple, so a vector is a tuple! 242*cda5da8dSAndroid Build Coastguard Worker 243*cda5da8dSAndroid Build Coastguard Worker Provides (for a, b vectors, k number): 244*cda5da8dSAndroid Build Coastguard Worker a+b vector addition 245*cda5da8dSAndroid Build Coastguard Worker a-b vector subtraction 246*cda5da8dSAndroid Build Coastguard Worker a*b inner product 247*cda5da8dSAndroid Build Coastguard Worker k*a and a*k multiplication with scalar 248*cda5da8dSAndroid Build Coastguard Worker |a| absolute value of a 249*cda5da8dSAndroid Build Coastguard Worker a.rotate(angle) rotation 250*cda5da8dSAndroid Build Coastguard Worker """ 251*cda5da8dSAndroid Build Coastguard Worker def __new__(cls, x, y): 252*cda5da8dSAndroid Build Coastguard Worker return tuple.__new__(cls, (x, y)) 253*cda5da8dSAndroid Build Coastguard Worker def __add__(self, other): 254*cda5da8dSAndroid Build Coastguard Worker return Vec2D(self[0]+other[0], self[1]+other[1]) 255*cda5da8dSAndroid Build Coastguard Worker def __mul__(self, other): 256*cda5da8dSAndroid Build Coastguard Worker if isinstance(other, Vec2D): 257*cda5da8dSAndroid Build Coastguard Worker return self[0]*other[0]+self[1]*other[1] 258*cda5da8dSAndroid Build Coastguard Worker return Vec2D(self[0]*other, self[1]*other) 259*cda5da8dSAndroid Build Coastguard Worker def __rmul__(self, other): 260*cda5da8dSAndroid Build Coastguard Worker if isinstance(other, int) or isinstance(other, float): 261*cda5da8dSAndroid Build Coastguard Worker return Vec2D(self[0]*other, self[1]*other) 262*cda5da8dSAndroid Build Coastguard Worker return NotImplemented 263*cda5da8dSAndroid Build Coastguard Worker def __sub__(self, other): 264*cda5da8dSAndroid Build Coastguard Worker return Vec2D(self[0]-other[0], self[1]-other[1]) 265*cda5da8dSAndroid Build Coastguard Worker def __neg__(self): 266*cda5da8dSAndroid Build Coastguard Worker return Vec2D(-self[0], -self[1]) 267*cda5da8dSAndroid Build Coastguard Worker def __abs__(self): 268*cda5da8dSAndroid Build Coastguard Worker return math.hypot(*self) 269*cda5da8dSAndroid Build Coastguard Worker def rotate(self, angle): 270*cda5da8dSAndroid Build Coastguard Worker """rotate self counterclockwise by angle 271*cda5da8dSAndroid Build Coastguard Worker """ 272*cda5da8dSAndroid Build Coastguard Worker perp = Vec2D(-self[1], self[0]) 273*cda5da8dSAndroid Build Coastguard Worker angle = math.radians(angle) 274*cda5da8dSAndroid Build Coastguard Worker c, s = math.cos(angle), math.sin(angle) 275*cda5da8dSAndroid Build Coastguard Worker return Vec2D(self[0]*c+perp[0]*s, self[1]*c+perp[1]*s) 276*cda5da8dSAndroid Build Coastguard Worker def __getnewargs__(self): 277*cda5da8dSAndroid Build Coastguard Worker return (self[0], self[1]) 278*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 279*cda5da8dSAndroid Build Coastguard Worker return "(%.2f,%.2f)" % self 280*cda5da8dSAndroid Build Coastguard Worker 281*cda5da8dSAndroid Build Coastguard Worker 282*cda5da8dSAndroid Build Coastguard Worker############################################################################## 283*cda5da8dSAndroid Build Coastguard Worker### From here up to line : Tkinter - Interface for turtle.py ### 284*cda5da8dSAndroid Build Coastguard Worker### May be replaced by an interface to some different graphics toolkit ### 285*cda5da8dSAndroid Build Coastguard Worker############################################################################## 286*cda5da8dSAndroid Build Coastguard Worker 287*cda5da8dSAndroid Build Coastguard Worker## helper functions for Scrolled Canvas, to forward Canvas-methods 288*cda5da8dSAndroid Build Coastguard Worker## to ScrolledCanvas class 289*cda5da8dSAndroid Build Coastguard Worker 290*cda5da8dSAndroid Build Coastguard Workerdef __methodDict(cls, _dict): 291*cda5da8dSAndroid Build Coastguard Worker """helper function for Scrolled Canvas""" 292*cda5da8dSAndroid Build Coastguard Worker baseList = list(cls.__bases__) 293*cda5da8dSAndroid Build Coastguard Worker baseList.reverse() 294*cda5da8dSAndroid Build Coastguard Worker for _super in baseList: 295*cda5da8dSAndroid Build Coastguard Worker __methodDict(_super, _dict) 296*cda5da8dSAndroid Build Coastguard Worker for key, value in cls.__dict__.items(): 297*cda5da8dSAndroid Build Coastguard Worker if type(value) == types.FunctionType: 298*cda5da8dSAndroid Build Coastguard Worker _dict[key] = value 299*cda5da8dSAndroid Build Coastguard Worker 300*cda5da8dSAndroid Build Coastguard Workerdef __methods(cls): 301*cda5da8dSAndroid Build Coastguard Worker """helper function for Scrolled Canvas""" 302*cda5da8dSAndroid Build Coastguard Worker _dict = {} 303*cda5da8dSAndroid Build Coastguard Worker __methodDict(cls, _dict) 304*cda5da8dSAndroid Build Coastguard Worker return _dict.keys() 305*cda5da8dSAndroid Build Coastguard Worker 306*cda5da8dSAndroid Build Coastguard Worker__stringBody = ( 307*cda5da8dSAndroid Build Coastguard Worker 'def %(method)s(self, *args, **kw): return ' + 308*cda5da8dSAndroid Build Coastguard Worker 'self.%(attribute)s.%(method)s(*args, **kw)') 309*cda5da8dSAndroid Build Coastguard Worker 310*cda5da8dSAndroid Build Coastguard Workerdef __forwardmethods(fromClass, toClass, toPart, exclude = ()): 311*cda5da8dSAndroid Build Coastguard Worker ### MANY CHANGES ### 312*cda5da8dSAndroid Build Coastguard Worker _dict_1 = {} 313*cda5da8dSAndroid Build Coastguard Worker __methodDict(toClass, _dict_1) 314*cda5da8dSAndroid Build Coastguard Worker _dict = {} 315*cda5da8dSAndroid Build Coastguard Worker mfc = __methods(fromClass) 316*cda5da8dSAndroid Build Coastguard Worker for ex in _dict_1.keys(): 317*cda5da8dSAndroid Build Coastguard Worker if ex[:1] == '_' or ex[-1:] == '_' or ex in exclude or ex in mfc: 318*cda5da8dSAndroid Build Coastguard Worker pass 319*cda5da8dSAndroid Build Coastguard Worker else: 320*cda5da8dSAndroid Build Coastguard Worker _dict[ex] = _dict_1[ex] 321*cda5da8dSAndroid Build Coastguard Worker 322*cda5da8dSAndroid Build Coastguard Worker for method, func in _dict.items(): 323*cda5da8dSAndroid Build Coastguard Worker d = {'method': method, 'func': func} 324*cda5da8dSAndroid Build Coastguard Worker if isinstance(toPart, str): 325*cda5da8dSAndroid Build Coastguard Worker execString = \ 326*cda5da8dSAndroid Build Coastguard Worker __stringBody % {'method' : method, 'attribute' : toPart} 327*cda5da8dSAndroid Build Coastguard Worker exec(execString, d) 328*cda5da8dSAndroid Build Coastguard Worker setattr(fromClass, method, d[method]) ### NEWU! 329*cda5da8dSAndroid Build Coastguard Worker 330*cda5da8dSAndroid Build Coastguard Worker 331*cda5da8dSAndroid Build Coastguard Workerclass ScrolledCanvas(TK.Frame): 332*cda5da8dSAndroid Build Coastguard Worker """Modeled after the scrolled canvas class from Grayons's Tkinter book. 333*cda5da8dSAndroid Build Coastguard Worker 334*cda5da8dSAndroid Build Coastguard Worker Used as the default canvas, which pops up automatically when 335*cda5da8dSAndroid Build Coastguard Worker using turtle graphics functions or the Turtle class. 336*cda5da8dSAndroid Build Coastguard Worker """ 337*cda5da8dSAndroid Build Coastguard Worker def __init__(self, master, width=500, height=350, 338*cda5da8dSAndroid Build Coastguard Worker canvwidth=600, canvheight=500): 339*cda5da8dSAndroid Build Coastguard Worker TK.Frame.__init__(self, master, width=width, height=height) 340*cda5da8dSAndroid Build Coastguard Worker self._rootwindow = self.winfo_toplevel() 341*cda5da8dSAndroid Build Coastguard Worker self.width, self.height = width, height 342*cda5da8dSAndroid Build Coastguard Worker self.canvwidth, self.canvheight = canvwidth, canvheight 343*cda5da8dSAndroid Build Coastguard Worker self.bg = "white" 344*cda5da8dSAndroid Build Coastguard Worker self._canvas = TK.Canvas(master, width=width, height=height, 345*cda5da8dSAndroid Build Coastguard Worker bg=self.bg, relief=TK.SUNKEN, borderwidth=2) 346*cda5da8dSAndroid Build Coastguard Worker self.hscroll = TK.Scrollbar(master, command=self._canvas.xview, 347*cda5da8dSAndroid Build Coastguard Worker orient=TK.HORIZONTAL) 348*cda5da8dSAndroid Build Coastguard Worker self.vscroll = TK.Scrollbar(master, command=self._canvas.yview) 349*cda5da8dSAndroid Build Coastguard Worker self._canvas.configure(xscrollcommand=self.hscroll.set, 350*cda5da8dSAndroid Build Coastguard Worker yscrollcommand=self.vscroll.set) 351*cda5da8dSAndroid Build Coastguard Worker self.rowconfigure(0, weight=1, minsize=0) 352*cda5da8dSAndroid Build Coastguard Worker self.columnconfigure(0, weight=1, minsize=0) 353*cda5da8dSAndroid Build Coastguard Worker self._canvas.grid(padx=1, in_ = self, pady=1, row=0, 354*cda5da8dSAndroid Build Coastguard Worker column=0, rowspan=1, columnspan=1, sticky='news') 355*cda5da8dSAndroid Build Coastguard Worker self.vscroll.grid(padx=1, in_ = self, pady=1, row=0, 356*cda5da8dSAndroid Build Coastguard Worker column=1, rowspan=1, columnspan=1, sticky='news') 357*cda5da8dSAndroid Build Coastguard Worker self.hscroll.grid(padx=1, in_ = self, pady=1, row=1, 358*cda5da8dSAndroid Build Coastguard Worker column=0, rowspan=1, columnspan=1, sticky='news') 359*cda5da8dSAndroid Build Coastguard Worker self.reset() 360*cda5da8dSAndroid Build Coastguard Worker self._rootwindow.bind('<Configure>', self.onResize) 361*cda5da8dSAndroid Build Coastguard Worker 362*cda5da8dSAndroid Build Coastguard Worker def reset(self, canvwidth=None, canvheight=None, bg = None): 363*cda5da8dSAndroid Build Coastguard Worker """Adjust canvas and scrollbars according to given canvas size.""" 364*cda5da8dSAndroid Build Coastguard Worker if canvwidth: 365*cda5da8dSAndroid Build Coastguard Worker self.canvwidth = canvwidth 366*cda5da8dSAndroid Build Coastguard Worker if canvheight: 367*cda5da8dSAndroid Build Coastguard Worker self.canvheight = canvheight 368*cda5da8dSAndroid Build Coastguard Worker if bg: 369*cda5da8dSAndroid Build Coastguard Worker self.bg = bg 370*cda5da8dSAndroid Build Coastguard Worker self._canvas.config(bg=bg, 371*cda5da8dSAndroid Build Coastguard Worker scrollregion=(-self.canvwidth//2, -self.canvheight//2, 372*cda5da8dSAndroid Build Coastguard Worker self.canvwidth//2, self.canvheight//2)) 373*cda5da8dSAndroid Build Coastguard Worker self._canvas.xview_moveto(0.5*(self.canvwidth - self.width + 30) / 374*cda5da8dSAndroid Build Coastguard Worker self.canvwidth) 375*cda5da8dSAndroid Build Coastguard Worker self._canvas.yview_moveto(0.5*(self.canvheight- self.height + 30) / 376*cda5da8dSAndroid Build Coastguard Worker self.canvheight) 377*cda5da8dSAndroid Build Coastguard Worker self.adjustScrolls() 378*cda5da8dSAndroid Build Coastguard Worker 379*cda5da8dSAndroid Build Coastguard Worker 380*cda5da8dSAndroid Build Coastguard Worker def adjustScrolls(self): 381*cda5da8dSAndroid Build Coastguard Worker """ Adjust scrollbars according to window- and canvas-size. 382*cda5da8dSAndroid Build Coastguard Worker """ 383*cda5da8dSAndroid Build Coastguard Worker cwidth = self._canvas.winfo_width() 384*cda5da8dSAndroid Build Coastguard Worker cheight = self._canvas.winfo_height() 385*cda5da8dSAndroid Build Coastguard Worker self._canvas.xview_moveto(0.5*(self.canvwidth-cwidth)/self.canvwidth) 386*cda5da8dSAndroid Build Coastguard Worker self._canvas.yview_moveto(0.5*(self.canvheight-cheight)/self.canvheight) 387*cda5da8dSAndroid Build Coastguard Worker if cwidth < self.canvwidth or cheight < self.canvheight: 388*cda5da8dSAndroid Build Coastguard Worker self.hscroll.grid(padx=1, in_ = self, pady=1, row=1, 389*cda5da8dSAndroid Build Coastguard Worker column=0, rowspan=1, columnspan=1, sticky='news') 390*cda5da8dSAndroid Build Coastguard Worker self.vscroll.grid(padx=1, in_ = self, pady=1, row=0, 391*cda5da8dSAndroid Build Coastguard Worker column=1, rowspan=1, columnspan=1, sticky='news') 392*cda5da8dSAndroid Build Coastguard Worker else: 393*cda5da8dSAndroid Build Coastguard Worker self.hscroll.grid_forget() 394*cda5da8dSAndroid Build Coastguard Worker self.vscroll.grid_forget() 395*cda5da8dSAndroid Build Coastguard Worker 396*cda5da8dSAndroid Build Coastguard Worker def onResize(self, event): 397*cda5da8dSAndroid Build Coastguard Worker """self-explanatory""" 398*cda5da8dSAndroid Build Coastguard Worker self.adjustScrolls() 399*cda5da8dSAndroid Build Coastguard Worker 400*cda5da8dSAndroid Build Coastguard Worker def bbox(self, *args): 401*cda5da8dSAndroid Build Coastguard Worker """ 'forward' method, which canvas itself has inherited... 402*cda5da8dSAndroid Build Coastguard Worker """ 403*cda5da8dSAndroid Build Coastguard Worker return self._canvas.bbox(*args) 404*cda5da8dSAndroid Build Coastguard Worker 405*cda5da8dSAndroid Build Coastguard Worker def cget(self, *args, **kwargs): 406*cda5da8dSAndroid Build Coastguard Worker """ 'forward' method, which canvas itself has inherited... 407*cda5da8dSAndroid Build Coastguard Worker """ 408*cda5da8dSAndroid Build Coastguard Worker return self._canvas.cget(*args, **kwargs) 409*cda5da8dSAndroid Build Coastguard Worker 410*cda5da8dSAndroid Build Coastguard Worker def config(self, *args, **kwargs): 411*cda5da8dSAndroid Build Coastguard Worker """ 'forward' method, which canvas itself has inherited... 412*cda5da8dSAndroid Build Coastguard Worker """ 413*cda5da8dSAndroid Build Coastguard Worker self._canvas.config(*args, **kwargs) 414*cda5da8dSAndroid Build Coastguard Worker 415*cda5da8dSAndroid Build Coastguard Worker def bind(self, *args, **kwargs): 416*cda5da8dSAndroid Build Coastguard Worker """ 'forward' method, which canvas itself has inherited... 417*cda5da8dSAndroid Build Coastguard Worker """ 418*cda5da8dSAndroid Build Coastguard Worker self._canvas.bind(*args, **kwargs) 419*cda5da8dSAndroid Build Coastguard Worker 420*cda5da8dSAndroid Build Coastguard Worker def unbind(self, *args, **kwargs): 421*cda5da8dSAndroid Build Coastguard Worker """ 'forward' method, which canvas itself has inherited... 422*cda5da8dSAndroid Build Coastguard Worker """ 423*cda5da8dSAndroid Build Coastguard Worker self._canvas.unbind(*args, **kwargs) 424*cda5da8dSAndroid Build Coastguard Worker 425*cda5da8dSAndroid Build Coastguard Worker def focus_force(self): 426*cda5da8dSAndroid Build Coastguard Worker """ 'forward' method, which canvas itself has inherited... 427*cda5da8dSAndroid Build Coastguard Worker """ 428*cda5da8dSAndroid Build Coastguard Worker self._canvas.focus_force() 429*cda5da8dSAndroid Build Coastguard Worker 430*cda5da8dSAndroid Build Coastguard Worker__forwardmethods(ScrolledCanvas, TK.Canvas, '_canvas') 431*cda5da8dSAndroid Build Coastguard Worker 432*cda5da8dSAndroid Build Coastguard Worker 433*cda5da8dSAndroid Build Coastguard Workerclass _Root(TK.Tk): 434*cda5da8dSAndroid Build Coastguard Worker """Root class for Screen based on Tkinter.""" 435*cda5da8dSAndroid Build Coastguard Worker def __init__(self): 436*cda5da8dSAndroid Build Coastguard Worker TK.Tk.__init__(self) 437*cda5da8dSAndroid Build Coastguard Worker 438*cda5da8dSAndroid Build Coastguard Worker def setupcanvas(self, width, height, cwidth, cheight): 439*cda5da8dSAndroid Build Coastguard Worker self._canvas = ScrolledCanvas(self, width, height, cwidth, cheight) 440*cda5da8dSAndroid Build Coastguard Worker self._canvas.pack(expand=1, fill="both") 441*cda5da8dSAndroid Build Coastguard Worker 442*cda5da8dSAndroid Build Coastguard Worker def _getcanvas(self): 443*cda5da8dSAndroid Build Coastguard Worker return self._canvas 444*cda5da8dSAndroid Build Coastguard Worker 445*cda5da8dSAndroid Build Coastguard Worker def set_geometry(self, width, height, startx, starty): 446*cda5da8dSAndroid Build Coastguard Worker self.geometry("%dx%d%+d%+d"%(width, height, startx, starty)) 447*cda5da8dSAndroid Build Coastguard Worker 448*cda5da8dSAndroid Build Coastguard Worker def ondestroy(self, destroy): 449*cda5da8dSAndroid Build Coastguard Worker self.wm_protocol("WM_DELETE_WINDOW", destroy) 450*cda5da8dSAndroid Build Coastguard Worker 451*cda5da8dSAndroid Build Coastguard Worker def win_width(self): 452*cda5da8dSAndroid Build Coastguard Worker return self.winfo_screenwidth() 453*cda5da8dSAndroid Build Coastguard Worker 454*cda5da8dSAndroid Build Coastguard Worker def win_height(self): 455*cda5da8dSAndroid Build Coastguard Worker return self.winfo_screenheight() 456*cda5da8dSAndroid Build Coastguard Worker 457*cda5da8dSAndroid Build Coastguard WorkerCanvas = TK.Canvas 458*cda5da8dSAndroid Build Coastguard Worker 459*cda5da8dSAndroid Build Coastguard Worker 460*cda5da8dSAndroid Build Coastguard Workerclass TurtleScreenBase(object): 461*cda5da8dSAndroid Build Coastguard Worker """Provide the basic graphics functionality. 462*cda5da8dSAndroid Build Coastguard Worker Interface between Tkinter and turtle.py. 463*cda5da8dSAndroid Build Coastguard Worker 464*cda5da8dSAndroid Build Coastguard Worker To port turtle.py to some different graphics toolkit 465*cda5da8dSAndroid Build Coastguard Worker a corresponding TurtleScreenBase class has to be implemented. 466*cda5da8dSAndroid Build Coastguard Worker """ 467*cda5da8dSAndroid Build Coastguard Worker 468*cda5da8dSAndroid Build Coastguard Worker def _blankimage(self): 469*cda5da8dSAndroid Build Coastguard Worker """return a blank image object 470*cda5da8dSAndroid Build Coastguard Worker """ 471*cda5da8dSAndroid Build Coastguard Worker img = TK.PhotoImage(width=1, height=1, master=self.cv) 472*cda5da8dSAndroid Build Coastguard Worker img.blank() 473*cda5da8dSAndroid Build Coastguard Worker return img 474*cda5da8dSAndroid Build Coastguard Worker 475*cda5da8dSAndroid Build Coastguard Worker def _image(self, filename): 476*cda5da8dSAndroid Build Coastguard Worker """return an image object containing the 477*cda5da8dSAndroid Build Coastguard Worker imagedata from a gif-file named filename. 478*cda5da8dSAndroid Build Coastguard Worker """ 479*cda5da8dSAndroid Build Coastguard Worker return TK.PhotoImage(file=filename, master=self.cv) 480*cda5da8dSAndroid Build Coastguard Worker 481*cda5da8dSAndroid Build Coastguard Worker def __init__(self, cv): 482*cda5da8dSAndroid Build Coastguard Worker self.cv = cv 483*cda5da8dSAndroid Build Coastguard Worker if isinstance(cv, ScrolledCanvas): 484*cda5da8dSAndroid Build Coastguard Worker w = self.cv.canvwidth 485*cda5da8dSAndroid Build Coastguard Worker h = self.cv.canvheight 486*cda5da8dSAndroid Build Coastguard Worker else: # expected: ordinary TK.Canvas 487*cda5da8dSAndroid Build Coastguard Worker w = int(self.cv.cget("width")) 488*cda5da8dSAndroid Build Coastguard Worker h = int(self.cv.cget("height")) 489*cda5da8dSAndroid Build Coastguard Worker self.cv.config(scrollregion = (-w//2, -h//2, w//2, h//2 )) 490*cda5da8dSAndroid Build Coastguard Worker self.canvwidth = w 491*cda5da8dSAndroid Build Coastguard Worker self.canvheight = h 492*cda5da8dSAndroid Build Coastguard Worker self.xscale = self.yscale = 1.0 493*cda5da8dSAndroid Build Coastguard Worker 494*cda5da8dSAndroid Build Coastguard Worker def _createpoly(self): 495*cda5da8dSAndroid Build Coastguard Worker """Create an invisible polygon item on canvas self.cv) 496*cda5da8dSAndroid Build Coastguard Worker """ 497*cda5da8dSAndroid Build Coastguard Worker return self.cv.create_polygon((0, 0, 0, 0, 0, 0), fill="", outline="") 498*cda5da8dSAndroid Build Coastguard Worker 499*cda5da8dSAndroid Build Coastguard Worker def _drawpoly(self, polyitem, coordlist, fill=None, 500*cda5da8dSAndroid Build Coastguard Worker outline=None, width=None, top=False): 501*cda5da8dSAndroid Build Coastguard Worker """Configure polygonitem polyitem according to provided 502*cda5da8dSAndroid Build Coastguard Worker arguments: 503*cda5da8dSAndroid Build Coastguard Worker coordlist is sequence of coordinates 504*cda5da8dSAndroid Build Coastguard Worker fill is filling color 505*cda5da8dSAndroid Build Coastguard Worker outline is outline color 506*cda5da8dSAndroid Build Coastguard Worker top is a boolean value, which specifies if polyitem 507*cda5da8dSAndroid Build Coastguard Worker will be put on top of the canvas' displaylist so it 508*cda5da8dSAndroid Build Coastguard Worker will not be covered by other items. 509*cda5da8dSAndroid Build Coastguard Worker """ 510*cda5da8dSAndroid Build Coastguard Worker cl = [] 511*cda5da8dSAndroid Build Coastguard Worker for x, y in coordlist: 512*cda5da8dSAndroid Build Coastguard Worker cl.append(x * self.xscale) 513*cda5da8dSAndroid Build Coastguard Worker cl.append(-y * self.yscale) 514*cda5da8dSAndroid Build Coastguard Worker self.cv.coords(polyitem, *cl) 515*cda5da8dSAndroid Build Coastguard Worker if fill is not None: 516*cda5da8dSAndroid Build Coastguard Worker self.cv.itemconfigure(polyitem, fill=fill) 517*cda5da8dSAndroid Build Coastguard Worker if outline is not None: 518*cda5da8dSAndroid Build Coastguard Worker self.cv.itemconfigure(polyitem, outline=outline) 519*cda5da8dSAndroid Build Coastguard Worker if width is not None: 520*cda5da8dSAndroid Build Coastguard Worker self.cv.itemconfigure(polyitem, width=width) 521*cda5da8dSAndroid Build Coastguard Worker if top: 522*cda5da8dSAndroid Build Coastguard Worker self.cv.tag_raise(polyitem) 523*cda5da8dSAndroid Build Coastguard Worker 524*cda5da8dSAndroid Build Coastguard Worker def _createline(self): 525*cda5da8dSAndroid Build Coastguard Worker """Create an invisible line item on canvas self.cv) 526*cda5da8dSAndroid Build Coastguard Worker """ 527*cda5da8dSAndroid Build Coastguard Worker return self.cv.create_line(0, 0, 0, 0, fill="", width=2, 528*cda5da8dSAndroid Build Coastguard Worker capstyle = TK.ROUND) 529*cda5da8dSAndroid Build Coastguard Worker 530*cda5da8dSAndroid Build Coastguard Worker def _drawline(self, lineitem, coordlist=None, 531*cda5da8dSAndroid Build Coastguard Worker fill=None, width=None, top=False): 532*cda5da8dSAndroid Build Coastguard Worker """Configure lineitem according to provided arguments: 533*cda5da8dSAndroid Build Coastguard Worker coordlist is sequence of coordinates 534*cda5da8dSAndroid Build Coastguard Worker fill is drawing color 535*cda5da8dSAndroid Build Coastguard Worker width is width of drawn line. 536*cda5da8dSAndroid Build Coastguard Worker top is a boolean value, which specifies if polyitem 537*cda5da8dSAndroid Build Coastguard Worker will be put on top of the canvas' displaylist so it 538*cda5da8dSAndroid Build Coastguard Worker will not be covered by other items. 539*cda5da8dSAndroid Build Coastguard Worker """ 540*cda5da8dSAndroid Build Coastguard Worker if coordlist is not None: 541*cda5da8dSAndroid Build Coastguard Worker cl = [] 542*cda5da8dSAndroid Build Coastguard Worker for x, y in coordlist: 543*cda5da8dSAndroid Build Coastguard Worker cl.append(x * self.xscale) 544*cda5da8dSAndroid Build Coastguard Worker cl.append(-y * self.yscale) 545*cda5da8dSAndroid Build Coastguard Worker self.cv.coords(lineitem, *cl) 546*cda5da8dSAndroid Build Coastguard Worker if fill is not None: 547*cda5da8dSAndroid Build Coastguard Worker self.cv.itemconfigure(lineitem, fill=fill) 548*cda5da8dSAndroid Build Coastguard Worker if width is not None: 549*cda5da8dSAndroid Build Coastguard Worker self.cv.itemconfigure(lineitem, width=width) 550*cda5da8dSAndroid Build Coastguard Worker if top: 551*cda5da8dSAndroid Build Coastguard Worker self.cv.tag_raise(lineitem) 552*cda5da8dSAndroid Build Coastguard Worker 553*cda5da8dSAndroid Build Coastguard Worker def _delete(self, item): 554*cda5da8dSAndroid Build Coastguard Worker """Delete graphics item from canvas. 555*cda5da8dSAndroid Build Coastguard Worker If item is"all" delete all graphics items. 556*cda5da8dSAndroid Build Coastguard Worker """ 557*cda5da8dSAndroid Build Coastguard Worker self.cv.delete(item) 558*cda5da8dSAndroid Build Coastguard Worker 559*cda5da8dSAndroid Build Coastguard Worker def _update(self): 560*cda5da8dSAndroid Build Coastguard Worker """Redraw graphics items on canvas 561*cda5da8dSAndroid Build Coastguard Worker """ 562*cda5da8dSAndroid Build Coastguard Worker self.cv.update() 563*cda5da8dSAndroid Build Coastguard Worker 564*cda5da8dSAndroid Build Coastguard Worker def _delay(self, delay): 565*cda5da8dSAndroid Build Coastguard Worker """Delay subsequent canvas actions for delay ms.""" 566*cda5da8dSAndroid Build Coastguard Worker self.cv.after(delay) 567*cda5da8dSAndroid Build Coastguard Worker 568*cda5da8dSAndroid Build Coastguard Worker def _iscolorstring(self, color): 569*cda5da8dSAndroid Build Coastguard Worker """Check if the string color is a legal Tkinter color string. 570*cda5da8dSAndroid Build Coastguard Worker """ 571*cda5da8dSAndroid Build Coastguard Worker try: 572*cda5da8dSAndroid Build Coastguard Worker rgb = self.cv.winfo_rgb(color) 573*cda5da8dSAndroid Build Coastguard Worker ok = True 574*cda5da8dSAndroid Build Coastguard Worker except TK.TclError: 575*cda5da8dSAndroid Build Coastguard Worker ok = False 576*cda5da8dSAndroid Build Coastguard Worker return ok 577*cda5da8dSAndroid Build Coastguard Worker 578*cda5da8dSAndroid Build Coastguard Worker def _bgcolor(self, color=None): 579*cda5da8dSAndroid Build Coastguard Worker """Set canvas' backgroundcolor if color is not None, 580*cda5da8dSAndroid Build Coastguard Worker else return backgroundcolor.""" 581*cda5da8dSAndroid Build Coastguard Worker if color is not None: 582*cda5da8dSAndroid Build Coastguard Worker self.cv.config(bg = color) 583*cda5da8dSAndroid Build Coastguard Worker self._update() 584*cda5da8dSAndroid Build Coastguard Worker else: 585*cda5da8dSAndroid Build Coastguard Worker return self.cv.cget("bg") 586*cda5da8dSAndroid Build Coastguard Worker 587*cda5da8dSAndroid Build Coastguard Worker def _write(self, pos, txt, align, font, pencolor): 588*cda5da8dSAndroid Build Coastguard Worker """Write txt at pos in canvas with specified font 589*cda5da8dSAndroid Build Coastguard Worker and color. 590*cda5da8dSAndroid Build Coastguard Worker Return text item and x-coord of right bottom corner 591*cda5da8dSAndroid Build Coastguard Worker of text's bounding box.""" 592*cda5da8dSAndroid Build Coastguard Worker x, y = pos 593*cda5da8dSAndroid Build Coastguard Worker x = x * self.xscale 594*cda5da8dSAndroid Build Coastguard Worker y = y * self.yscale 595*cda5da8dSAndroid Build Coastguard Worker anchor = {"left":"sw", "center":"s", "right":"se" } 596*cda5da8dSAndroid Build Coastguard Worker item = self.cv.create_text(x-1, -y, text = txt, anchor = anchor[align], 597*cda5da8dSAndroid Build Coastguard Worker fill = pencolor, font = font) 598*cda5da8dSAndroid Build Coastguard Worker x0, y0, x1, y1 = self.cv.bbox(item) 599*cda5da8dSAndroid Build Coastguard Worker return item, x1-1 600*cda5da8dSAndroid Build Coastguard Worker 601*cda5da8dSAndroid Build Coastguard Worker## def _dot(self, pos, size, color): 602*cda5da8dSAndroid Build Coastguard Worker## """may be implemented for some other graphics toolkit""" 603*cda5da8dSAndroid Build Coastguard Worker 604*cda5da8dSAndroid Build Coastguard Worker def _onclick(self, item, fun, num=1, add=None): 605*cda5da8dSAndroid Build Coastguard Worker """Bind fun to mouse-click event on turtle. 606*cda5da8dSAndroid Build Coastguard Worker fun must be a function with two arguments, the coordinates 607*cda5da8dSAndroid Build Coastguard Worker of the clicked point on the canvas. 608*cda5da8dSAndroid Build Coastguard Worker num, the number of the mouse-button defaults to 1 609*cda5da8dSAndroid Build Coastguard Worker """ 610*cda5da8dSAndroid Build Coastguard Worker if fun is None: 611*cda5da8dSAndroid Build Coastguard Worker self.cv.tag_unbind(item, "<Button-%s>" % num) 612*cda5da8dSAndroid Build Coastguard Worker else: 613*cda5da8dSAndroid Build Coastguard Worker def eventfun(event): 614*cda5da8dSAndroid Build Coastguard Worker x, y = (self.cv.canvasx(event.x)/self.xscale, 615*cda5da8dSAndroid Build Coastguard Worker -self.cv.canvasy(event.y)/self.yscale) 616*cda5da8dSAndroid Build Coastguard Worker fun(x, y) 617*cda5da8dSAndroid Build Coastguard Worker self.cv.tag_bind(item, "<Button-%s>" % num, eventfun, add) 618*cda5da8dSAndroid Build Coastguard Worker 619*cda5da8dSAndroid Build Coastguard Worker def _onrelease(self, item, fun, num=1, add=None): 620*cda5da8dSAndroid Build Coastguard Worker """Bind fun to mouse-button-release event on turtle. 621*cda5da8dSAndroid Build Coastguard Worker fun must be a function with two arguments, the coordinates 622*cda5da8dSAndroid Build Coastguard Worker of the point on the canvas where mouse button is released. 623*cda5da8dSAndroid Build Coastguard Worker num, the number of the mouse-button defaults to 1 624*cda5da8dSAndroid Build Coastguard Worker 625*cda5da8dSAndroid Build Coastguard Worker If a turtle is clicked, first _onclick-event will be performed, 626*cda5da8dSAndroid Build Coastguard Worker then _onscreensclick-event. 627*cda5da8dSAndroid Build Coastguard Worker """ 628*cda5da8dSAndroid Build Coastguard Worker if fun is None: 629*cda5da8dSAndroid Build Coastguard Worker self.cv.tag_unbind(item, "<Button%s-ButtonRelease>" % num) 630*cda5da8dSAndroid Build Coastguard Worker else: 631*cda5da8dSAndroid Build Coastguard Worker def eventfun(event): 632*cda5da8dSAndroid Build Coastguard Worker x, y = (self.cv.canvasx(event.x)/self.xscale, 633*cda5da8dSAndroid Build Coastguard Worker -self.cv.canvasy(event.y)/self.yscale) 634*cda5da8dSAndroid Build Coastguard Worker fun(x, y) 635*cda5da8dSAndroid Build Coastguard Worker self.cv.tag_bind(item, "<Button%s-ButtonRelease>" % num, 636*cda5da8dSAndroid Build Coastguard Worker eventfun, add) 637*cda5da8dSAndroid Build Coastguard Worker 638*cda5da8dSAndroid Build Coastguard Worker def _ondrag(self, item, fun, num=1, add=None): 639*cda5da8dSAndroid Build Coastguard Worker """Bind fun to mouse-move-event (with pressed mouse button) on turtle. 640*cda5da8dSAndroid Build Coastguard Worker fun must be a function with two arguments, the coordinates of the 641*cda5da8dSAndroid Build Coastguard Worker actual mouse position on the canvas. 642*cda5da8dSAndroid Build Coastguard Worker num, the number of the mouse-button defaults to 1 643*cda5da8dSAndroid Build Coastguard Worker 644*cda5da8dSAndroid Build Coastguard Worker Every sequence of mouse-move-events on a turtle is preceded by a 645*cda5da8dSAndroid Build Coastguard Worker mouse-click event on that turtle. 646*cda5da8dSAndroid Build Coastguard Worker """ 647*cda5da8dSAndroid Build Coastguard Worker if fun is None: 648*cda5da8dSAndroid Build Coastguard Worker self.cv.tag_unbind(item, "<Button%s-Motion>" % num) 649*cda5da8dSAndroid Build Coastguard Worker else: 650*cda5da8dSAndroid Build Coastguard Worker def eventfun(event): 651*cda5da8dSAndroid Build Coastguard Worker try: 652*cda5da8dSAndroid Build Coastguard Worker x, y = (self.cv.canvasx(event.x)/self.xscale, 653*cda5da8dSAndroid Build Coastguard Worker -self.cv.canvasy(event.y)/self.yscale) 654*cda5da8dSAndroid Build Coastguard Worker fun(x, y) 655*cda5da8dSAndroid Build Coastguard Worker except Exception: 656*cda5da8dSAndroid Build Coastguard Worker pass 657*cda5da8dSAndroid Build Coastguard Worker self.cv.tag_bind(item, "<Button%s-Motion>" % num, eventfun, add) 658*cda5da8dSAndroid Build Coastguard Worker 659*cda5da8dSAndroid Build Coastguard Worker def _onscreenclick(self, fun, num=1, add=None): 660*cda5da8dSAndroid Build Coastguard Worker """Bind fun to mouse-click event on canvas. 661*cda5da8dSAndroid Build Coastguard Worker fun must be a function with two arguments, the coordinates 662*cda5da8dSAndroid Build Coastguard Worker of the clicked point on the canvas. 663*cda5da8dSAndroid Build Coastguard Worker num, the number of the mouse-button defaults to 1 664*cda5da8dSAndroid Build Coastguard Worker 665*cda5da8dSAndroid Build Coastguard Worker If a turtle is clicked, first _onclick-event will be performed, 666*cda5da8dSAndroid Build Coastguard Worker then _onscreensclick-event. 667*cda5da8dSAndroid Build Coastguard Worker """ 668*cda5da8dSAndroid Build Coastguard Worker if fun is None: 669*cda5da8dSAndroid Build Coastguard Worker self.cv.unbind("<Button-%s>" % num) 670*cda5da8dSAndroid Build Coastguard Worker else: 671*cda5da8dSAndroid Build Coastguard Worker def eventfun(event): 672*cda5da8dSAndroid Build Coastguard Worker x, y = (self.cv.canvasx(event.x)/self.xscale, 673*cda5da8dSAndroid Build Coastguard Worker -self.cv.canvasy(event.y)/self.yscale) 674*cda5da8dSAndroid Build Coastguard Worker fun(x, y) 675*cda5da8dSAndroid Build Coastguard Worker self.cv.bind("<Button-%s>" % num, eventfun, add) 676*cda5da8dSAndroid Build Coastguard Worker 677*cda5da8dSAndroid Build Coastguard Worker def _onkeyrelease(self, fun, key): 678*cda5da8dSAndroid Build Coastguard Worker """Bind fun to key-release event of key. 679*cda5da8dSAndroid Build Coastguard Worker Canvas must have focus. See method listen 680*cda5da8dSAndroid Build Coastguard Worker """ 681*cda5da8dSAndroid Build Coastguard Worker if fun is None: 682*cda5da8dSAndroid Build Coastguard Worker self.cv.unbind("<KeyRelease-%s>" % key, None) 683*cda5da8dSAndroid Build Coastguard Worker else: 684*cda5da8dSAndroid Build Coastguard Worker def eventfun(event): 685*cda5da8dSAndroid Build Coastguard Worker fun() 686*cda5da8dSAndroid Build Coastguard Worker self.cv.bind("<KeyRelease-%s>" % key, eventfun) 687*cda5da8dSAndroid Build Coastguard Worker 688*cda5da8dSAndroid Build Coastguard Worker def _onkeypress(self, fun, key=None): 689*cda5da8dSAndroid Build Coastguard Worker """If key is given, bind fun to key-press event of key. 690*cda5da8dSAndroid Build Coastguard Worker Otherwise bind fun to any key-press. 691*cda5da8dSAndroid Build Coastguard Worker Canvas must have focus. See method listen. 692*cda5da8dSAndroid Build Coastguard Worker """ 693*cda5da8dSAndroid Build Coastguard Worker if fun is None: 694*cda5da8dSAndroid Build Coastguard Worker if key is None: 695*cda5da8dSAndroid Build Coastguard Worker self.cv.unbind("<KeyPress>", None) 696*cda5da8dSAndroid Build Coastguard Worker else: 697*cda5da8dSAndroid Build Coastguard Worker self.cv.unbind("<KeyPress-%s>" % key, None) 698*cda5da8dSAndroid Build Coastguard Worker else: 699*cda5da8dSAndroid Build Coastguard Worker def eventfun(event): 700*cda5da8dSAndroid Build Coastguard Worker fun() 701*cda5da8dSAndroid Build Coastguard Worker if key is None: 702*cda5da8dSAndroid Build Coastguard Worker self.cv.bind("<KeyPress>", eventfun) 703*cda5da8dSAndroid Build Coastguard Worker else: 704*cda5da8dSAndroid Build Coastguard Worker self.cv.bind("<KeyPress-%s>" % key, eventfun) 705*cda5da8dSAndroid Build Coastguard Worker 706*cda5da8dSAndroid Build Coastguard Worker def _listen(self): 707*cda5da8dSAndroid Build Coastguard Worker """Set focus on canvas (in order to collect key-events) 708*cda5da8dSAndroid Build Coastguard Worker """ 709*cda5da8dSAndroid Build Coastguard Worker self.cv.focus_force() 710*cda5da8dSAndroid Build Coastguard Worker 711*cda5da8dSAndroid Build Coastguard Worker def _ontimer(self, fun, t): 712*cda5da8dSAndroid Build Coastguard Worker """Install a timer, which calls fun after t milliseconds. 713*cda5da8dSAndroid Build Coastguard Worker """ 714*cda5da8dSAndroid Build Coastguard Worker if t == 0: 715*cda5da8dSAndroid Build Coastguard Worker self.cv.after_idle(fun) 716*cda5da8dSAndroid Build Coastguard Worker else: 717*cda5da8dSAndroid Build Coastguard Worker self.cv.after(t, fun) 718*cda5da8dSAndroid Build Coastguard Worker 719*cda5da8dSAndroid Build Coastguard Worker def _createimage(self, image): 720*cda5da8dSAndroid Build Coastguard Worker """Create and return image item on canvas. 721*cda5da8dSAndroid Build Coastguard Worker """ 722*cda5da8dSAndroid Build Coastguard Worker return self.cv.create_image(0, 0, image=image) 723*cda5da8dSAndroid Build Coastguard Worker 724*cda5da8dSAndroid Build Coastguard Worker def _drawimage(self, item, pos, image): 725*cda5da8dSAndroid Build Coastguard Worker """Configure image item as to draw image object 726*cda5da8dSAndroid Build Coastguard Worker at position (x,y) on canvas) 727*cda5da8dSAndroid Build Coastguard Worker """ 728*cda5da8dSAndroid Build Coastguard Worker x, y = pos 729*cda5da8dSAndroid Build Coastguard Worker self.cv.coords(item, (x * self.xscale, -y * self.yscale)) 730*cda5da8dSAndroid Build Coastguard Worker self.cv.itemconfig(item, image=image) 731*cda5da8dSAndroid Build Coastguard Worker 732*cda5da8dSAndroid Build Coastguard Worker def _setbgpic(self, item, image): 733*cda5da8dSAndroid Build Coastguard Worker """Configure image item as to draw image object 734*cda5da8dSAndroid Build Coastguard Worker at center of canvas. Set item to the first item 735*cda5da8dSAndroid Build Coastguard Worker in the displaylist, so it will be drawn below 736*cda5da8dSAndroid Build Coastguard Worker any other item .""" 737*cda5da8dSAndroid Build Coastguard Worker self.cv.itemconfig(item, image=image) 738*cda5da8dSAndroid Build Coastguard Worker self.cv.tag_lower(item) 739*cda5da8dSAndroid Build Coastguard Worker 740*cda5da8dSAndroid Build Coastguard Worker def _type(self, item): 741*cda5da8dSAndroid Build Coastguard Worker """Return 'line' or 'polygon' or 'image' depending on 742*cda5da8dSAndroid Build Coastguard Worker type of item. 743*cda5da8dSAndroid Build Coastguard Worker """ 744*cda5da8dSAndroid Build Coastguard Worker return self.cv.type(item) 745*cda5da8dSAndroid Build Coastguard Worker 746*cda5da8dSAndroid Build Coastguard Worker def _pointlist(self, item): 747*cda5da8dSAndroid Build Coastguard Worker """returns list of coordinate-pairs of points of item 748*cda5da8dSAndroid Build Coastguard Worker Example (for insiders): 749*cda5da8dSAndroid Build Coastguard Worker >>> from turtle import * 750*cda5da8dSAndroid Build Coastguard Worker >>> getscreen()._pointlist(getturtle().turtle._item) 751*cda5da8dSAndroid Build Coastguard Worker [(0.0, 9.9999999999999982), (0.0, -9.9999999999999982), 752*cda5da8dSAndroid Build Coastguard Worker (9.9999999999999982, 0.0)] 753*cda5da8dSAndroid Build Coastguard Worker >>> """ 754*cda5da8dSAndroid Build Coastguard Worker cl = self.cv.coords(item) 755*cda5da8dSAndroid Build Coastguard Worker pl = [(cl[i], -cl[i+1]) for i in range(0, len(cl), 2)] 756*cda5da8dSAndroid Build Coastguard Worker return pl 757*cda5da8dSAndroid Build Coastguard Worker 758*cda5da8dSAndroid Build Coastguard Worker def _setscrollregion(self, srx1, sry1, srx2, sry2): 759*cda5da8dSAndroid Build Coastguard Worker self.cv.config(scrollregion=(srx1, sry1, srx2, sry2)) 760*cda5da8dSAndroid Build Coastguard Worker 761*cda5da8dSAndroid Build Coastguard Worker def _rescale(self, xscalefactor, yscalefactor): 762*cda5da8dSAndroid Build Coastguard Worker items = self.cv.find_all() 763*cda5da8dSAndroid Build Coastguard Worker for item in items: 764*cda5da8dSAndroid Build Coastguard Worker coordinates = list(self.cv.coords(item)) 765*cda5da8dSAndroid Build Coastguard Worker newcoordlist = [] 766*cda5da8dSAndroid Build Coastguard Worker while coordinates: 767*cda5da8dSAndroid Build Coastguard Worker x, y = coordinates[:2] 768*cda5da8dSAndroid Build Coastguard Worker newcoordlist.append(x * xscalefactor) 769*cda5da8dSAndroid Build Coastguard Worker newcoordlist.append(y * yscalefactor) 770*cda5da8dSAndroid Build Coastguard Worker coordinates = coordinates[2:] 771*cda5da8dSAndroid Build Coastguard Worker self.cv.coords(item, *newcoordlist) 772*cda5da8dSAndroid Build Coastguard Worker 773*cda5da8dSAndroid Build Coastguard Worker def _resize(self, canvwidth=None, canvheight=None, bg=None): 774*cda5da8dSAndroid Build Coastguard Worker """Resize the canvas the turtles are drawing on. Does 775*cda5da8dSAndroid Build Coastguard Worker not alter the drawing window. 776*cda5da8dSAndroid Build Coastguard Worker """ 777*cda5da8dSAndroid Build Coastguard Worker # needs amendment 778*cda5da8dSAndroid Build Coastguard Worker if not isinstance(self.cv, ScrolledCanvas): 779*cda5da8dSAndroid Build Coastguard Worker return self.canvwidth, self.canvheight 780*cda5da8dSAndroid Build Coastguard Worker if canvwidth is canvheight is bg is None: 781*cda5da8dSAndroid Build Coastguard Worker return self.cv.canvwidth, self.cv.canvheight 782*cda5da8dSAndroid Build Coastguard Worker if canvwidth is not None: 783*cda5da8dSAndroid Build Coastguard Worker self.canvwidth = canvwidth 784*cda5da8dSAndroid Build Coastguard Worker if canvheight is not None: 785*cda5da8dSAndroid Build Coastguard Worker self.canvheight = canvheight 786*cda5da8dSAndroid Build Coastguard Worker self.cv.reset(canvwidth, canvheight, bg) 787*cda5da8dSAndroid Build Coastguard Worker 788*cda5da8dSAndroid Build Coastguard Worker def _window_size(self): 789*cda5da8dSAndroid Build Coastguard Worker """ Return the width and height of the turtle window. 790*cda5da8dSAndroid Build Coastguard Worker """ 791*cda5da8dSAndroid Build Coastguard Worker width = self.cv.winfo_width() 792*cda5da8dSAndroid Build Coastguard Worker if width <= 1: # the window isn't managed by a geometry manager 793*cda5da8dSAndroid Build Coastguard Worker width = self.cv['width'] 794*cda5da8dSAndroid Build Coastguard Worker height = self.cv.winfo_height() 795*cda5da8dSAndroid Build Coastguard Worker if height <= 1: # the window isn't managed by a geometry manager 796*cda5da8dSAndroid Build Coastguard Worker height = self.cv['height'] 797*cda5da8dSAndroid Build Coastguard Worker return width, height 798*cda5da8dSAndroid Build Coastguard Worker 799*cda5da8dSAndroid Build Coastguard Worker def mainloop(self): 800*cda5da8dSAndroid Build Coastguard Worker """Starts event loop - calling Tkinter's mainloop function. 801*cda5da8dSAndroid Build Coastguard Worker 802*cda5da8dSAndroid Build Coastguard Worker No argument. 803*cda5da8dSAndroid Build Coastguard Worker 804*cda5da8dSAndroid Build Coastguard Worker Must be last statement in a turtle graphics program. 805*cda5da8dSAndroid Build Coastguard Worker Must NOT be used if a script is run from within IDLE in -n mode 806*cda5da8dSAndroid Build Coastguard Worker (No subprocess) - for interactive use of turtle graphics. 807*cda5da8dSAndroid Build Coastguard Worker 808*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 809*cda5da8dSAndroid Build Coastguard Worker >>> screen.mainloop() 810*cda5da8dSAndroid Build Coastguard Worker 811*cda5da8dSAndroid Build Coastguard Worker """ 812*cda5da8dSAndroid Build Coastguard Worker self.cv.tk.mainloop() 813*cda5da8dSAndroid Build Coastguard Worker 814*cda5da8dSAndroid Build Coastguard Worker def textinput(self, title, prompt): 815*cda5da8dSAndroid Build Coastguard Worker """Pop up a dialog window for input of a string. 816*cda5da8dSAndroid Build Coastguard Worker 817*cda5da8dSAndroid Build Coastguard Worker Arguments: title is the title of the dialog window, 818*cda5da8dSAndroid Build Coastguard Worker prompt is a text mostly describing what information to input. 819*cda5da8dSAndroid Build Coastguard Worker 820*cda5da8dSAndroid Build Coastguard Worker Return the string input 821*cda5da8dSAndroid Build Coastguard Worker If the dialog is canceled, return None. 822*cda5da8dSAndroid Build Coastguard Worker 823*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 824*cda5da8dSAndroid Build Coastguard Worker >>> screen.textinput("NIM", "Name of first player:") 825*cda5da8dSAndroid Build Coastguard Worker 826*cda5da8dSAndroid Build Coastguard Worker """ 827*cda5da8dSAndroid Build Coastguard Worker return simpledialog.askstring(title, prompt, parent=self.cv) 828*cda5da8dSAndroid Build Coastguard Worker 829*cda5da8dSAndroid Build Coastguard Worker def numinput(self, title, prompt, default=None, minval=None, maxval=None): 830*cda5da8dSAndroid Build Coastguard Worker """Pop up a dialog window for input of a number. 831*cda5da8dSAndroid Build Coastguard Worker 832*cda5da8dSAndroid Build Coastguard Worker Arguments: title is the title of the dialog window, 833*cda5da8dSAndroid Build Coastguard Worker prompt is a text mostly describing what numerical information to input. 834*cda5da8dSAndroid Build Coastguard Worker default: default value 835*cda5da8dSAndroid Build Coastguard Worker minval: minimum value for input 836*cda5da8dSAndroid Build Coastguard Worker maxval: maximum value for input 837*cda5da8dSAndroid Build Coastguard Worker 838*cda5da8dSAndroid Build Coastguard Worker The number input must be in the range minval .. maxval if these are 839*cda5da8dSAndroid Build Coastguard Worker given. If not, a hint is issued and the dialog remains open for 840*cda5da8dSAndroid Build Coastguard Worker correction. Return the number input. 841*cda5da8dSAndroid Build Coastguard Worker If the dialog is canceled, return None. 842*cda5da8dSAndroid Build Coastguard Worker 843*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 844*cda5da8dSAndroid Build Coastguard Worker >>> screen.numinput("Poker", "Your stakes:", 1000, minval=10, maxval=10000) 845*cda5da8dSAndroid Build Coastguard Worker 846*cda5da8dSAndroid Build Coastguard Worker """ 847*cda5da8dSAndroid Build Coastguard Worker return simpledialog.askfloat(title, prompt, initialvalue=default, 848*cda5da8dSAndroid Build Coastguard Worker minvalue=minval, maxvalue=maxval, 849*cda5da8dSAndroid Build Coastguard Worker parent=self.cv) 850*cda5da8dSAndroid Build Coastguard Worker 851*cda5da8dSAndroid Build Coastguard Worker 852*cda5da8dSAndroid Build Coastguard Worker############################################################################## 853*cda5da8dSAndroid Build Coastguard Worker### End of Tkinter - interface ### 854*cda5da8dSAndroid Build Coastguard Worker############################################################################## 855*cda5da8dSAndroid Build Coastguard Worker 856*cda5da8dSAndroid Build Coastguard Worker 857*cda5da8dSAndroid Build Coastguard Workerclass Terminator (Exception): 858*cda5da8dSAndroid Build Coastguard Worker """Will be raised in TurtleScreen.update, if _RUNNING becomes False. 859*cda5da8dSAndroid Build Coastguard Worker 860*cda5da8dSAndroid Build Coastguard Worker This stops execution of a turtle graphics script. 861*cda5da8dSAndroid Build Coastguard Worker Main purpose: use in the Demo-Viewer turtle.Demo.py. 862*cda5da8dSAndroid Build Coastguard Worker """ 863*cda5da8dSAndroid Build Coastguard Worker pass 864*cda5da8dSAndroid Build Coastguard Worker 865*cda5da8dSAndroid Build Coastguard Worker 866*cda5da8dSAndroid Build Coastguard Workerclass TurtleGraphicsError(Exception): 867*cda5da8dSAndroid Build Coastguard Worker """Some TurtleGraphics Error 868*cda5da8dSAndroid Build Coastguard Worker """ 869*cda5da8dSAndroid Build Coastguard Worker 870*cda5da8dSAndroid Build Coastguard Worker 871*cda5da8dSAndroid Build Coastguard Workerclass Shape(object): 872*cda5da8dSAndroid Build Coastguard Worker """Data structure modeling shapes. 873*cda5da8dSAndroid Build Coastguard Worker 874*cda5da8dSAndroid Build Coastguard Worker attribute _type is one of "polygon", "image", "compound" 875*cda5da8dSAndroid Build Coastguard Worker attribute _data is - depending on _type a poygon-tuple, 876*cda5da8dSAndroid Build Coastguard Worker an image or a list constructed using the addcomponent method. 877*cda5da8dSAndroid Build Coastguard Worker """ 878*cda5da8dSAndroid Build Coastguard Worker def __init__(self, type_, data=None): 879*cda5da8dSAndroid Build Coastguard Worker self._type = type_ 880*cda5da8dSAndroid Build Coastguard Worker if type_ == "polygon": 881*cda5da8dSAndroid Build Coastguard Worker if isinstance(data, list): 882*cda5da8dSAndroid Build Coastguard Worker data = tuple(data) 883*cda5da8dSAndroid Build Coastguard Worker elif type_ == "image": 884*cda5da8dSAndroid Build Coastguard Worker if isinstance(data, str): 885*cda5da8dSAndroid Build Coastguard Worker if data.lower().endswith(".gif") and isfile(data): 886*cda5da8dSAndroid Build Coastguard Worker data = TurtleScreen._image(data) 887*cda5da8dSAndroid Build Coastguard Worker # else data assumed to be Photoimage 888*cda5da8dSAndroid Build Coastguard Worker elif type_ == "compound": 889*cda5da8dSAndroid Build Coastguard Worker data = [] 890*cda5da8dSAndroid Build Coastguard Worker else: 891*cda5da8dSAndroid Build Coastguard Worker raise TurtleGraphicsError("There is no shape type %s" % type_) 892*cda5da8dSAndroid Build Coastguard Worker self._data = data 893*cda5da8dSAndroid Build Coastguard Worker 894*cda5da8dSAndroid Build Coastguard Worker def addcomponent(self, poly, fill, outline=None): 895*cda5da8dSAndroid Build Coastguard Worker """Add component to a shape of type compound. 896*cda5da8dSAndroid Build Coastguard Worker 897*cda5da8dSAndroid Build Coastguard Worker Arguments: poly is a polygon, i. e. a tuple of number pairs. 898*cda5da8dSAndroid Build Coastguard Worker fill is the fillcolor of the component, 899*cda5da8dSAndroid Build Coastguard Worker outline is the outline color of the component. 900*cda5da8dSAndroid Build Coastguard Worker 901*cda5da8dSAndroid Build Coastguard Worker call (for a Shapeobject namend s): 902*cda5da8dSAndroid Build Coastguard Worker -- s.addcomponent(((0,0), (10,10), (-10,10)), "red", "blue") 903*cda5da8dSAndroid Build Coastguard Worker 904*cda5da8dSAndroid Build Coastguard Worker Example: 905*cda5da8dSAndroid Build Coastguard Worker >>> poly = ((0,0),(10,-5),(0,10),(-10,-5)) 906*cda5da8dSAndroid Build Coastguard Worker >>> s = Shape("compound") 907*cda5da8dSAndroid Build Coastguard Worker >>> s.addcomponent(poly, "red", "blue") 908*cda5da8dSAndroid Build Coastguard Worker >>> # .. add more components and then use register_shape() 909*cda5da8dSAndroid Build Coastguard Worker """ 910*cda5da8dSAndroid Build Coastguard Worker if self._type != "compound": 911*cda5da8dSAndroid Build Coastguard Worker raise TurtleGraphicsError("Cannot add component to %s Shape" 912*cda5da8dSAndroid Build Coastguard Worker % self._type) 913*cda5da8dSAndroid Build Coastguard Worker if outline is None: 914*cda5da8dSAndroid Build Coastguard Worker outline = fill 915*cda5da8dSAndroid Build Coastguard Worker self._data.append([poly, fill, outline]) 916*cda5da8dSAndroid Build Coastguard Worker 917*cda5da8dSAndroid Build Coastguard Worker 918*cda5da8dSAndroid Build Coastguard Workerclass Tbuffer(object): 919*cda5da8dSAndroid Build Coastguard Worker """Ring buffer used as undobuffer for RawTurtle objects.""" 920*cda5da8dSAndroid Build Coastguard Worker def __init__(self, bufsize=10): 921*cda5da8dSAndroid Build Coastguard Worker self.bufsize = bufsize 922*cda5da8dSAndroid Build Coastguard Worker self.buffer = [[None]] * bufsize 923*cda5da8dSAndroid Build Coastguard Worker self.ptr = -1 924*cda5da8dSAndroid Build Coastguard Worker self.cumulate = False 925*cda5da8dSAndroid Build Coastguard Worker def reset(self, bufsize=None): 926*cda5da8dSAndroid Build Coastguard Worker if bufsize is None: 927*cda5da8dSAndroid Build Coastguard Worker for i in range(self.bufsize): 928*cda5da8dSAndroid Build Coastguard Worker self.buffer[i] = [None] 929*cda5da8dSAndroid Build Coastguard Worker else: 930*cda5da8dSAndroid Build Coastguard Worker self.bufsize = bufsize 931*cda5da8dSAndroid Build Coastguard Worker self.buffer = [[None]] * bufsize 932*cda5da8dSAndroid Build Coastguard Worker self.ptr = -1 933*cda5da8dSAndroid Build Coastguard Worker def push(self, item): 934*cda5da8dSAndroid Build Coastguard Worker if self.bufsize > 0: 935*cda5da8dSAndroid Build Coastguard Worker if not self.cumulate: 936*cda5da8dSAndroid Build Coastguard Worker self.ptr = (self.ptr + 1) % self.bufsize 937*cda5da8dSAndroid Build Coastguard Worker self.buffer[self.ptr] = item 938*cda5da8dSAndroid Build Coastguard Worker else: 939*cda5da8dSAndroid Build Coastguard Worker self.buffer[self.ptr].append(item) 940*cda5da8dSAndroid Build Coastguard Worker def pop(self): 941*cda5da8dSAndroid Build Coastguard Worker if self.bufsize > 0: 942*cda5da8dSAndroid Build Coastguard Worker item = self.buffer[self.ptr] 943*cda5da8dSAndroid Build Coastguard Worker if item is None: 944*cda5da8dSAndroid Build Coastguard Worker return None 945*cda5da8dSAndroid Build Coastguard Worker else: 946*cda5da8dSAndroid Build Coastguard Worker self.buffer[self.ptr] = [None] 947*cda5da8dSAndroid Build Coastguard Worker self.ptr = (self.ptr - 1) % self.bufsize 948*cda5da8dSAndroid Build Coastguard Worker return (item) 949*cda5da8dSAndroid Build Coastguard Worker def nr_of_items(self): 950*cda5da8dSAndroid Build Coastguard Worker return self.bufsize - self.buffer.count([None]) 951*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 952*cda5da8dSAndroid Build Coastguard Worker return str(self.buffer) + " " + str(self.ptr) 953*cda5da8dSAndroid Build Coastguard Worker 954*cda5da8dSAndroid Build Coastguard Worker 955*cda5da8dSAndroid Build Coastguard Worker 956*cda5da8dSAndroid Build Coastguard Workerclass TurtleScreen(TurtleScreenBase): 957*cda5da8dSAndroid Build Coastguard Worker """Provides screen oriented methods like bgcolor etc. 958*cda5da8dSAndroid Build Coastguard Worker 959*cda5da8dSAndroid Build Coastguard Worker Only relies upon the methods of TurtleScreenBase and NOT 960*cda5da8dSAndroid Build Coastguard Worker upon components of the underlying graphics toolkit - 961*cda5da8dSAndroid Build Coastguard Worker which is Tkinter in this case. 962*cda5da8dSAndroid Build Coastguard Worker """ 963*cda5da8dSAndroid Build Coastguard Worker _RUNNING = True 964*cda5da8dSAndroid Build Coastguard Worker 965*cda5da8dSAndroid Build Coastguard Worker def __init__(self, cv, mode=_CFG["mode"], 966*cda5da8dSAndroid Build Coastguard Worker colormode=_CFG["colormode"], delay=_CFG["delay"]): 967*cda5da8dSAndroid Build Coastguard Worker TurtleScreenBase.__init__(self, cv) 968*cda5da8dSAndroid Build Coastguard Worker 969*cda5da8dSAndroid Build Coastguard Worker self._shapes = { 970*cda5da8dSAndroid Build Coastguard Worker "arrow" : Shape("polygon", ((-10,0), (10,0), (0,10))), 971*cda5da8dSAndroid Build Coastguard Worker "turtle" : Shape("polygon", ((0,16), (-2,14), (-1,10), (-4,7), 972*cda5da8dSAndroid Build Coastguard Worker (-7,9), (-9,8), (-6,5), (-7,1), (-5,-3), (-8,-6), 973*cda5da8dSAndroid Build Coastguard Worker (-6,-8), (-4,-5), (0,-7), (4,-5), (6,-8), (8,-6), 974*cda5da8dSAndroid Build Coastguard Worker (5,-3), (7,1), (6,5), (9,8), (7,9), (4,7), (1,10), 975*cda5da8dSAndroid Build Coastguard Worker (2,14))), 976*cda5da8dSAndroid Build Coastguard Worker "circle" : Shape("polygon", ((10,0), (9.51,3.09), (8.09,5.88), 977*cda5da8dSAndroid Build Coastguard Worker (5.88,8.09), (3.09,9.51), (0,10), (-3.09,9.51), 978*cda5da8dSAndroid Build Coastguard Worker (-5.88,8.09), (-8.09,5.88), (-9.51,3.09), (-10,0), 979*cda5da8dSAndroid Build Coastguard Worker (-9.51,-3.09), (-8.09,-5.88), (-5.88,-8.09), 980*cda5da8dSAndroid Build Coastguard Worker (-3.09,-9.51), (-0.00,-10.00), (3.09,-9.51), 981*cda5da8dSAndroid Build Coastguard Worker (5.88,-8.09), (8.09,-5.88), (9.51,-3.09))), 982*cda5da8dSAndroid Build Coastguard Worker "square" : Shape("polygon", ((10,-10), (10,10), (-10,10), 983*cda5da8dSAndroid Build Coastguard Worker (-10,-10))), 984*cda5da8dSAndroid Build Coastguard Worker "triangle" : Shape("polygon", ((10,-5.77), (0,11.55), 985*cda5da8dSAndroid Build Coastguard Worker (-10,-5.77))), 986*cda5da8dSAndroid Build Coastguard Worker "classic": Shape("polygon", ((0,0),(-5,-9),(0,-7),(5,-9))), 987*cda5da8dSAndroid Build Coastguard Worker "blank" : Shape("image", self._blankimage()) 988*cda5da8dSAndroid Build Coastguard Worker } 989*cda5da8dSAndroid Build Coastguard Worker 990*cda5da8dSAndroid Build Coastguard Worker self._bgpics = {"nopic" : ""} 991*cda5da8dSAndroid Build Coastguard Worker 992*cda5da8dSAndroid Build Coastguard Worker self._mode = mode 993*cda5da8dSAndroid Build Coastguard Worker self._delayvalue = delay 994*cda5da8dSAndroid Build Coastguard Worker self._colormode = _CFG["colormode"] 995*cda5da8dSAndroid Build Coastguard Worker self._keys = [] 996*cda5da8dSAndroid Build Coastguard Worker self.clear() 997*cda5da8dSAndroid Build Coastguard Worker if sys.platform == 'darwin': 998*cda5da8dSAndroid Build Coastguard Worker # Force Turtle window to the front on OS X. This is needed because 999*cda5da8dSAndroid Build Coastguard Worker # the Turtle window will show behind the Terminal window when you 1000*cda5da8dSAndroid Build Coastguard Worker # start the demo from the command line. 1001*cda5da8dSAndroid Build Coastguard Worker rootwindow = cv.winfo_toplevel() 1002*cda5da8dSAndroid Build Coastguard Worker rootwindow.call('wm', 'attributes', '.', '-topmost', '1') 1003*cda5da8dSAndroid Build Coastguard Worker rootwindow.call('wm', 'attributes', '.', '-topmost', '0') 1004*cda5da8dSAndroid Build Coastguard Worker 1005*cda5da8dSAndroid Build Coastguard Worker def clear(self): 1006*cda5da8dSAndroid Build Coastguard Worker """Delete all drawings and all turtles from the TurtleScreen. 1007*cda5da8dSAndroid Build Coastguard Worker 1008*cda5da8dSAndroid Build Coastguard Worker No argument. 1009*cda5da8dSAndroid Build Coastguard Worker 1010*cda5da8dSAndroid Build Coastguard Worker Reset empty TurtleScreen to its initial state: white background, 1011*cda5da8dSAndroid Build Coastguard Worker no backgroundimage, no eventbindings and tracing on. 1012*cda5da8dSAndroid Build Coastguard Worker 1013*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1014*cda5da8dSAndroid Build Coastguard Worker >>> screen.clear() 1015*cda5da8dSAndroid Build Coastguard Worker 1016*cda5da8dSAndroid Build Coastguard Worker Note: this method is not available as function. 1017*cda5da8dSAndroid Build Coastguard Worker """ 1018*cda5da8dSAndroid Build Coastguard Worker self._delayvalue = _CFG["delay"] 1019*cda5da8dSAndroid Build Coastguard Worker self._colormode = _CFG["colormode"] 1020*cda5da8dSAndroid Build Coastguard Worker self._delete("all") 1021*cda5da8dSAndroid Build Coastguard Worker self._bgpic = self._createimage("") 1022*cda5da8dSAndroid Build Coastguard Worker self._bgpicname = "nopic" 1023*cda5da8dSAndroid Build Coastguard Worker self._tracing = 1 1024*cda5da8dSAndroid Build Coastguard Worker self._updatecounter = 0 1025*cda5da8dSAndroid Build Coastguard Worker self._turtles = [] 1026*cda5da8dSAndroid Build Coastguard Worker self.bgcolor("white") 1027*cda5da8dSAndroid Build Coastguard Worker for btn in 1, 2, 3: 1028*cda5da8dSAndroid Build Coastguard Worker self.onclick(None, btn) 1029*cda5da8dSAndroid Build Coastguard Worker self.onkeypress(None) 1030*cda5da8dSAndroid Build Coastguard Worker for key in self._keys[:]: 1031*cda5da8dSAndroid Build Coastguard Worker self.onkey(None, key) 1032*cda5da8dSAndroid Build Coastguard Worker self.onkeypress(None, key) 1033*cda5da8dSAndroid Build Coastguard Worker Turtle._pen = None 1034*cda5da8dSAndroid Build Coastguard Worker 1035*cda5da8dSAndroid Build Coastguard Worker def mode(self, mode=None): 1036*cda5da8dSAndroid Build Coastguard Worker """Set turtle-mode ('standard', 'logo' or 'world') and perform reset. 1037*cda5da8dSAndroid Build Coastguard Worker 1038*cda5da8dSAndroid Build Coastguard Worker Optional argument: 1039*cda5da8dSAndroid Build Coastguard Worker mode -- one of the strings 'standard', 'logo' or 'world' 1040*cda5da8dSAndroid Build Coastguard Worker 1041*cda5da8dSAndroid Build Coastguard Worker Mode 'standard' is compatible with turtle.py. 1042*cda5da8dSAndroid Build Coastguard Worker Mode 'logo' is compatible with most Logo-Turtle-Graphics. 1043*cda5da8dSAndroid Build Coastguard Worker Mode 'world' uses userdefined 'worldcoordinates'. *Attention*: in 1044*cda5da8dSAndroid Build Coastguard Worker this mode angles appear distorted if x/y unit-ratio doesn't equal 1. 1045*cda5da8dSAndroid Build Coastguard Worker If mode is not given, return the current mode. 1046*cda5da8dSAndroid Build Coastguard Worker 1047*cda5da8dSAndroid Build Coastguard Worker Mode Initial turtle heading positive angles 1048*cda5da8dSAndroid Build Coastguard Worker ------------|-------------------------|------------------- 1049*cda5da8dSAndroid Build Coastguard Worker 'standard' to the right (east) counterclockwise 1050*cda5da8dSAndroid Build Coastguard Worker 'logo' upward (north) clockwise 1051*cda5da8dSAndroid Build Coastguard Worker 1052*cda5da8dSAndroid Build Coastguard Worker Examples: 1053*cda5da8dSAndroid Build Coastguard Worker >>> mode('logo') # resets turtle heading to north 1054*cda5da8dSAndroid Build Coastguard Worker >>> mode() 1055*cda5da8dSAndroid Build Coastguard Worker 'logo' 1056*cda5da8dSAndroid Build Coastguard Worker """ 1057*cda5da8dSAndroid Build Coastguard Worker if mode is None: 1058*cda5da8dSAndroid Build Coastguard Worker return self._mode 1059*cda5da8dSAndroid Build Coastguard Worker mode = mode.lower() 1060*cda5da8dSAndroid Build Coastguard Worker if mode not in ["standard", "logo", "world"]: 1061*cda5da8dSAndroid Build Coastguard Worker raise TurtleGraphicsError("No turtle-graphics-mode %s" % mode) 1062*cda5da8dSAndroid Build Coastguard Worker self._mode = mode 1063*cda5da8dSAndroid Build Coastguard Worker if mode in ["standard", "logo"]: 1064*cda5da8dSAndroid Build Coastguard Worker self._setscrollregion(-self.canvwidth//2, -self.canvheight//2, 1065*cda5da8dSAndroid Build Coastguard Worker self.canvwidth//2, self.canvheight//2) 1066*cda5da8dSAndroid Build Coastguard Worker self.xscale = self.yscale = 1.0 1067*cda5da8dSAndroid Build Coastguard Worker self.reset() 1068*cda5da8dSAndroid Build Coastguard Worker 1069*cda5da8dSAndroid Build Coastguard Worker def setworldcoordinates(self, llx, lly, urx, ury): 1070*cda5da8dSAndroid Build Coastguard Worker """Set up a user defined coordinate-system. 1071*cda5da8dSAndroid Build Coastguard Worker 1072*cda5da8dSAndroid Build Coastguard Worker Arguments: 1073*cda5da8dSAndroid Build Coastguard Worker llx -- a number, x-coordinate of lower left corner of canvas 1074*cda5da8dSAndroid Build Coastguard Worker lly -- a number, y-coordinate of lower left corner of canvas 1075*cda5da8dSAndroid Build Coastguard Worker urx -- a number, x-coordinate of upper right corner of canvas 1076*cda5da8dSAndroid Build Coastguard Worker ury -- a number, y-coordinate of upper right corner of canvas 1077*cda5da8dSAndroid Build Coastguard Worker 1078*cda5da8dSAndroid Build Coastguard Worker Set up user coodinat-system and switch to mode 'world' if necessary. 1079*cda5da8dSAndroid Build Coastguard Worker This performs a screen.reset. If mode 'world' is already active, 1080*cda5da8dSAndroid Build Coastguard Worker all drawings are redrawn according to the new coordinates. 1081*cda5da8dSAndroid Build Coastguard Worker 1082*cda5da8dSAndroid Build Coastguard Worker But ATTENTION: in user-defined coordinatesystems angles may appear 1083*cda5da8dSAndroid Build Coastguard Worker distorted. (see Screen.mode()) 1084*cda5da8dSAndroid Build Coastguard Worker 1085*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1086*cda5da8dSAndroid Build Coastguard Worker >>> screen.setworldcoordinates(-10,-0.5,50,1.5) 1087*cda5da8dSAndroid Build Coastguard Worker >>> for _ in range(36): 1088*cda5da8dSAndroid Build Coastguard Worker ... left(10) 1089*cda5da8dSAndroid Build Coastguard Worker ... forward(0.5) 1090*cda5da8dSAndroid Build Coastguard Worker """ 1091*cda5da8dSAndroid Build Coastguard Worker if self.mode() != "world": 1092*cda5da8dSAndroid Build Coastguard Worker self.mode("world") 1093*cda5da8dSAndroid Build Coastguard Worker xspan = float(urx - llx) 1094*cda5da8dSAndroid Build Coastguard Worker yspan = float(ury - lly) 1095*cda5da8dSAndroid Build Coastguard Worker wx, wy = self._window_size() 1096*cda5da8dSAndroid Build Coastguard Worker self.screensize(wx-20, wy-20) 1097*cda5da8dSAndroid Build Coastguard Worker oldxscale, oldyscale = self.xscale, self.yscale 1098*cda5da8dSAndroid Build Coastguard Worker self.xscale = self.canvwidth / xspan 1099*cda5da8dSAndroid Build Coastguard Worker self.yscale = self.canvheight / yspan 1100*cda5da8dSAndroid Build Coastguard Worker srx1 = llx * self.xscale 1101*cda5da8dSAndroid Build Coastguard Worker sry1 = -ury * self.yscale 1102*cda5da8dSAndroid Build Coastguard Worker srx2 = self.canvwidth + srx1 1103*cda5da8dSAndroid Build Coastguard Worker sry2 = self.canvheight + sry1 1104*cda5da8dSAndroid Build Coastguard Worker self._setscrollregion(srx1, sry1, srx2, sry2) 1105*cda5da8dSAndroid Build Coastguard Worker self._rescale(self.xscale/oldxscale, self.yscale/oldyscale) 1106*cda5da8dSAndroid Build Coastguard Worker self.update() 1107*cda5da8dSAndroid Build Coastguard Worker 1108*cda5da8dSAndroid Build Coastguard Worker def register_shape(self, name, shape=None): 1109*cda5da8dSAndroid Build Coastguard Worker """Adds a turtle shape to TurtleScreen's shapelist. 1110*cda5da8dSAndroid Build Coastguard Worker 1111*cda5da8dSAndroid Build Coastguard Worker Arguments: 1112*cda5da8dSAndroid Build Coastguard Worker (1) name is the name of a gif-file and shape is None. 1113*cda5da8dSAndroid Build Coastguard Worker Installs the corresponding image shape. 1114*cda5da8dSAndroid Build Coastguard Worker !! Image-shapes DO NOT rotate when turning the turtle, 1115*cda5da8dSAndroid Build Coastguard Worker !! so they do not display the heading of the turtle! 1116*cda5da8dSAndroid Build Coastguard Worker (2) name is an arbitrary string and shape is a tuple 1117*cda5da8dSAndroid Build Coastguard Worker of pairs of coordinates. Installs the corresponding 1118*cda5da8dSAndroid Build Coastguard Worker polygon shape 1119*cda5da8dSAndroid Build Coastguard Worker (3) name is an arbitrary string and shape is a 1120*cda5da8dSAndroid Build Coastguard Worker (compound) Shape object. Installs the corresponding 1121*cda5da8dSAndroid Build Coastguard Worker compound shape. 1122*cda5da8dSAndroid Build Coastguard Worker To use a shape, you have to issue the command shape(shapename). 1123*cda5da8dSAndroid Build Coastguard Worker 1124*cda5da8dSAndroid Build Coastguard Worker call: register_shape("turtle.gif") 1125*cda5da8dSAndroid Build Coastguard Worker --or: register_shape("tri", ((0,0), (10,10), (-10,10))) 1126*cda5da8dSAndroid Build Coastguard Worker 1127*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1128*cda5da8dSAndroid Build Coastguard Worker >>> screen.register_shape("triangle", ((5,-3),(0,5),(-5,-3))) 1129*cda5da8dSAndroid Build Coastguard Worker 1130*cda5da8dSAndroid Build Coastguard Worker """ 1131*cda5da8dSAndroid Build Coastguard Worker if shape is None: 1132*cda5da8dSAndroid Build Coastguard Worker # image 1133*cda5da8dSAndroid Build Coastguard Worker if name.lower().endswith(".gif"): 1134*cda5da8dSAndroid Build Coastguard Worker shape = Shape("image", self._image(name)) 1135*cda5da8dSAndroid Build Coastguard Worker else: 1136*cda5da8dSAndroid Build Coastguard Worker raise TurtleGraphicsError("Bad arguments for register_shape.\n" 1137*cda5da8dSAndroid Build Coastguard Worker + "Use help(register_shape)" ) 1138*cda5da8dSAndroid Build Coastguard Worker elif isinstance(shape, tuple): 1139*cda5da8dSAndroid Build Coastguard Worker shape = Shape("polygon", shape) 1140*cda5da8dSAndroid Build Coastguard Worker ## else shape assumed to be Shape-instance 1141*cda5da8dSAndroid Build Coastguard Worker self._shapes[name] = shape 1142*cda5da8dSAndroid Build Coastguard Worker 1143*cda5da8dSAndroid Build Coastguard Worker def _colorstr(self, color): 1144*cda5da8dSAndroid Build Coastguard Worker """Return color string corresponding to args. 1145*cda5da8dSAndroid Build Coastguard Worker 1146*cda5da8dSAndroid Build Coastguard Worker Argument may be a string or a tuple of three 1147*cda5da8dSAndroid Build Coastguard Worker numbers corresponding to actual colormode, 1148*cda5da8dSAndroid Build Coastguard Worker i.e. in the range 0<=n<=colormode. 1149*cda5da8dSAndroid Build Coastguard Worker 1150*cda5da8dSAndroid Build Coastguard Worker If the argument doesn't represent a color, 1151*cda5da8dSAndroid Build Coastguard Worker an error is raised. 1152*cda5da8dSAndroid Build Coastguard Worker """ 1153*cda5da8dSAndroid Build Coastguard Worker if len(color) == 1: 1154*cda5da8dSAndroid Build Coastguard Worker color = color[0] 1155*cda5da8dSAndroid Build Coastguard Worker if isinstance(color, str): 1156*cda5da8dSAndroid Build Coastguard Worker if self._iscolorstring(color) or color == "": 1157*cda5da8dSAndroid Build Coastguard Worker return color 1158*cda5da8dSAndroid Build Coastguard Worker else: 1159*cda5da8dSAndroid Build Coastguard Worker raise TurtleGraphicsError("bad color string: %s" % str(color)) 1160*cda5da8dSAndroid Build Coastguard Worker try: 1161*cda5da8dSAndroid Build Coastguard Worker r, g, b = color 1162*cda5da8dSAndroid Build Coastguard Worker except (TypeError, ValueError): 1163*cda5da8dSAndroid Build Coastguard Worker raise TurtleGraphicsError("bad color arguments: %s" % str(color)) 1164*cda5da8dSAndroid Build Coastguard Worker if self._colormode == 1.0: 1165*cda5da8dSAndroid Build Coastguard Worker r, g, b = [round(255.0*x) for x in (r, g, b)] 1166*cda5da8dSAndroid Build Coastguard Worker if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)): 1167*cda5da8dSAndroid Build Coastguard Worker raise TurtleGraphicsError("bad color sequence: %s" % str(color)) 1168*cda5da8dSAndroid Build Coastguard Worker return "#%02x%02x%02x" % (r, g, b) 1169*cda5da8dSAndroid Build Coastguard Worker 1170*cda5da8dSAndroid Build Coastguard Worker def _color(self, cstr): 1171*cda5da8dSAndroid Build Coastguard Worker if not cstr.startswith("#"): 1172*cda5da8dSAndroid Build Coastguard Worker return cstr 1173*cda5da8dSAndroid Build Coastguard Worker if len(cstr) == 7: 1174*cda5da8dSAndroid Build Coastguard Worker cl = [int(cstr[i:i+2], 16) for i in (1, 3, 5)] 1175*cda5da8dSAndroid Build Coastguard Worker elif len(cstr) == 4: 1176*cda5da8dSAndroid Build Coastguard Worker cl = [16*int(cstr[h], 16) for h in cstr[1:]] 1177*cda5da8dSAndroid Build Coastguard Worker else: 1178*cda5da8dSAndroid Build Coastguard Worker raise TurtleGraphicsError("bad colorstring: %s" % cstr) 1179*cda5da8dSAndroid Build Coastguard Worker return tuple(c * self._colormode/255 for c in cl) 1180*cda5da8dSAndroid Build Coastguard Worker 1181*cda5da8dSAndroid Build Coastguard Worker def colormode(self, cmode=None): 1182*cda5da8dSAndroid Build Coastguard Worker """Return the colormode or set it to 1.0 or 255. 1183*cda5da8dSAndroid Build Coastguard Worker 1184*cda5da8dSAndroid Build Coastguard Worker Optional argument: 1185*cda5da8dSAndroid Build Coastguard Worker cmode -- one of the values 1.0 or 255 1186*cda5da8dSAndroid Build Coastguard Worker 1187*cda5da8dSAndroid Build Coastguard Worker r, g, b values of colortriples have to be in range 0..cmode. 1188*cda5da8dSAndroid Build Coastguard Worker 1189*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1190*cda5da8dSAndroid Build Coastguard Worker >>> screen.colormode() 1191*cda5da8dSAndroid Build Coastguard Worker 1.0 1192*cda5da8dSAndroid Build Coastguard Worker >>> screen.colormode(255) 1193*cda5da8dSAndroid Build Coastguard Worker >>> pencolor(240,160,80) 1194*cda5da8dSAndroid Build Coastguard Worker """ 1195*cda5da8dSAndroid Build Coastguard Worker if cmode is None: 1196*cda5da8dSAndroid Build Coastguard Worker return self._colormode 1197*cda5da8dSAndroid Build Coastguard Worker if cmode == 1.0: 1198*cda5da8dSAndroid Build Coastguard Worker self._colormode = float(cmode) 1199*cda5da8dSAndroid Build Coastguard Worker elif cmode == 255: 1200*cda5da8dSAndroid Build Coastguard Worker self._colormode = int(cmode) 1201*cda5da8dSAndroid Build Coastguard Worker 1202*cda5da8dSAndroid Build Coastguard Worker def reset(self): 1203*cda5da8dSAndroid Build Coastguard Worker """Reset all Turtles on the Screen to their initial state. 1204*cda5da8dSAndroid Build Coastguard Worker 1205*cda5da8dSAndroid Build Coastguard Worker No argument. 1206*cda5da8dSAndroid Build Coastguard Worker 1207*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1208*cda5da8dSAndroid Build Coastguard Worker >>> screen.reset() 1209*cda5da8dSAndroid Build Coastguard Worker """ 1210*cda5da8dSAndroid Build Coastguard Worker for turtle in self._turtles: 1211*cda5da8dSAndroid Build Coastguard Worker turtle._setmode(self._mode) 1212*cda5da8dSAndroid Build Coastguard Worker turtle.reset() 1213*cda5da8dSAndroid Build Coastguard Worker 1214*cda5da8dSAndroid Build Coastguard Worker def turtles(self): 1215*cda5da8dSAndroid Build Coastguard Worker """Return the list of turtles on the screen. 1216*cda5da8dSAndroid Build Coastguard Worker 1217*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1218*cda5da8dSAndroid Build Coastguard Worker >>> screen.turtles() 1219*cda5da8dSAndroid Build Coastguard Worker [<turtle.Turtle object at 0x00E11FB0>] 1220*cda5da8dSAndroid Build Coastguard Worker """ 1221*cda5da8dSAndroid Build Coastguard Worker return self._turtles 1222*cda5da8dSAndroid Build Coastguard Worker 1223*cda5da8dSAndroid Build Coastguard Worker def bgcolor(self, *args): 1224*cda5da8dSAndroid Build Coastguard Worker """Set or return backgroundcolor of the TurtleScreen. 1225*cda5da8dSAndroid Build Coastguard Worker 1226*cda5da8dSAndroid Build Coastguard Worker Arguments (if given): a color string or three numbers 1227*cda5da8dSAndroid Build Coastguard Worker in the range 0..colormode or a 3-tuple of such numbers. 1228*cda5da8dSAndroid Build Coastguard Worker 1229*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1230*cda5da8dSAndroid Build Coastguard Worker >>> screen.bgcolor("orange") 1231*cda5da8dSAndroid Build Coastguard Worker >>> screen.bgcolor() 1232*cda5da8dSAndroid Build Coastguard Worker 'orange' 1233*cda5da8dSAndroid Build Coastguard Worker >>> screen.bgcolor(0.5,0,0.5) 1234*cda5da8dSAndroid Build Coastguard Worker >>> screen.bgcolor() 1235*cda5da8dSAndroid Build Coastguard Worker '#800080' 1236*cda5da8dSAndroid Build Coastguard Worker """ 1237*cda5da8dSAndroid Build Coastguard Worker if args: 1238*cda5da8dSAndroid Build Coastguard Worker color = self._colorstr(args) 1239*cda5da8dSAndroid Build Coastguard Worker else: 1240*cda5da8dSAndroid Build Coastguard Worker color = None 1241*cda5da8dSAndroid Build Coastguard Worker color = self._bgcolor(color) 1242*cda5da8dSAndroid Build Coastguard Worker if color is not None: 1243*cda5da8dSAndroid Build Coastguard Worker color = self._color(color) 1244*cda5da8dSAndroid Build Coastguard Worker return color 1245*cda5da8dSAndroid Build Coastguard Worker 1246*cda5da8dSAndroid Build Coastguard Worker def tracer(self, n=None, delay=None): 1247*cda5da8dSAndroid Build Coastguard Worker """Turns turtle animation on/off and set delay for update drawings. 1248*cda5da8dSAndroid Build Coastguard Worker 1249*cda5da8dSAndroid Build Coastguard Worker Optional arguments: 1250*cda5da8dSAndroid Build Coastguard Worker n -- nonnegative integer 1251*cda5da8dSAndroid Build Coastguard Worker delay -- nonnegative integer 1252*cda5da8dSAndroid Build Coastguard Worker 1253*cda5da8dSAndroid Build Coastguard Worker If n is given, only each n-th regular screen update is really performed. 1254*cda5da8dSAndroid Build Coastguard Worker (Can be used to accelerate the drawing of complex graphics.) 1255*cda5da8dSAndroid Build Coastguard Worker Second arguments sets delay value (see RawTurtle.delay()) 1256*cda5da8dSAndroid Build Coastguard Worker 1257*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1258*cda5da8dSAndroid Build Coastguard Worker >>> screen.tracer(8, 25) 1259*cda5da8dSAndroid Build Coastguard Worker >>> dist = 2 1260*cda5da8dSAndroid Build Coastguard Worker >>> for i in range(200): 1261*cda5da8dSAndroid Build Coastguard Worker ... fd(dist) 1262*cda5da8dSAndroid Build Coastguard Worker ... rt(90) 1263*cda5da8dSAndroid Build Coastguard Worker ... dist += 2 1264*cda5da8dSAndroid Build Coastguard Worker """ 1265*cda5da8dSAndroid Build Coastguard Worker if n is None: 1266*cda5da8dSAndroid Build Coastguard Worker return self._tracing 1267*cda5da8dSAndroid Build Coastguard Worker self._tracing = int(n) 1268*cda5da8dSAndroid Build Coastguard Worker self._updatecounter = 0 1269*cda5da8dSAndroid Build Coastguard Worker if delay is not None: 1270*cda5da8dSAndroid Build Coastguard Worker self._delayvalue = int(delay) 1271*cda5da8dSAndroid Build Coastguard Worker if self._tracing: 1272*cda5da8dSAndroid Build Coastguard Worker self.update() 1273*cda5da8dSAndroid Build Coastguard Worker 1274*cda5da8dSAndroid Build Coastguard Worker def delay(self, delay=None): 1275*cda5da8dSAndroid Build Coastguard Worker """ Return or set the drawing delay in milliseconds. 1276*cda5da8dSAndroid Build Coastguard Worker 1277*cda5da8dSAndroid Build Coastguard Worker Optional argument: 1278*cda5da8dSAndroid Build Coastguard Worker delay -- positive integer 1279*cda5da8dSAndroid Build Coastguard Worker 1280*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1281*cda5da8dSAndroid Build Coastguard Worker >>> screen.delay(15) 1282*cda5da8dSAndroid Build Coastguard Worker >>> screen.delay() 1283*cda5da8dSAndroid Build Coastguard Worker 15 1284*cda5da8dSAndroid Build Coastguard Worker """ 1285*cda5da8dSAndroid Build Coastguard Worker if delay is None: 1286*cda5da8dSAndroid Build Coastguard Worker return self._delayvalue 1287*cda5da8dSAndroid Build Coastguard Worker self._delayvalue = int(delay) 1288*cda5da8dSAndroid Build Coastguard Worker 1289*cda5da8dSAndroid Build Coastguard Worker def _incrementudc(self): 1290*cda5da8dSAndroid Build Coastguard Worker """Increment update counter.""" 1291*cda5da8dSAndroid Build Coastguard Worker if not TurtleScreen._RUNNING: 1292*cda5da8dSAndroid Build Coastguard Worker TurtleScreen._RUNNING = True 1293*cda5da8dSAndroid Build Coastguard Worker raise Terminator 1294*cda5da8dSAndroid Build Coastguard Worker if self._tracing > 0: 1295*cda5da8dSAndroid Build Coastguard Worker self._updatecounter += 1 1296*cda5da8dSAndroid Build Coastguard Worker self._updatecounter %= self._tracing 1297*cda5da8dSAndroid Build Coastguard Worker 1298*cda5da8dSAndroid Build Coastguard Worker def update(self): 1299*cda5da8dSAndroid Build Coastguard Worker """Perform a TurtleScreen update. 1300*cda5da8dSAndroid Build Coastguard Worker """ 1301*cda5da8dSAndroid Build Coastguard Worker tracing = self._tracing 1302*cda5da8dSAndroid Build Coastguard Worker self._tracing = True 1303*cda5da8dSAndroid Build Coastguard Worker for t in self.turtles(): 1304*cda5da8dSAndroid Build Coastguard Worker t._update_data() 1305*cda5da8dSAndroid Build Coastguard Worker t._drawturtle() 1306*cda5da8dSAndroid Build Coastguard Worker self._tracing = tracing 1307*cda5da8dSAndroid Build Coastguard Worker self._update() 1308*cda5da8dSAndroid Build Coastguard Worker 1309*cda5da8dSAndroid Build Coastguard Worker def window_width(self): 1310*cda5da8dSAndroid Build Coastguard Worker """ Return the width of the turtle window. 1311*cda5da8dSAndroid Build Coastguard Worker 1312*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1313*cda5da8dSAndroid Build Coastguard Worker >>> screen.window_width() 1314*cda5da8dSAndroid Build Coastguard Worker 640 1315*cda5da8dSAndroid Build Coastguard Worker """ 1316*cda5da8dSAndroid Build Coastguard Worker return self._window_size()[0] 1317*cda5da8dSAndroid Build Coastguard Worker 1318*cda5da8dSAndroid Build Coastguard Worker def window_height(self): 1319*cda5da8dSAndroid Build Coastguard Worker """ Return the height of the turtle window. 1320*cda5da8dSAndroid Build Coastguard Worker 1321*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1322*cda5da8dSAndroid Build Coastguard Worker >>> screen.window_height() 1323*cda5da8dSAndroid Build Coastguard Worker 480 1324*cda5da8dSAndroid Build Coastguard Worker """ 1325*cda5da8dSAndroid Build Coastguard Worker return self._window_size()[1] 1326*cda5da8dSAndroid Build Coastguard Worker 1327*cda5da8dSAndroid Build Coastguard Worker def getcanvas(self): 1328*cda5da8dSAndroid Build Coastguard Worker """Return the Canvas of this TurtleScreen. 1329*cda5da8dSAndroid Build Coastguard Worker 1330*cda5da8dSAndroid Build Coastguard Worker No argument. 1331*cda5da8dSAndroid Build Coastguard Worker 1332*cda5da8dSAndroid Build Coastguard Worker Example (for a Screen instance named screen): 1333*cda5da8dSAndroid Build Coastguard Worker >>> cv = screen.getcanvas() 1334*cda5da8dSAndroid Build Coastguard Worker >>> cv 1335*cda5da8dSAndroid Build Coastguard Worker <turtle.ScrolledCanvas instance at 0x010742D8> 1336*cda5da8dSAndroid Build Coastguard Worker """ 1337*cda5da8dSAndroid Build Coastguard Worker return self.cv 1338*cda5da8dSAndroid Build Coastguard Worker 1339*cda5da8dSAndroid Build Coastguard Worker def getshapes(self): 1340*cda5da8dSAndroid Build Coastguard Worker """Return a list of names of all currently available turtle shapes. 1341*cda5da8dSAndroid Build Coastguard Worker 1342*cda5da8dSAndroid Build Coastguard Worker No argument. 1343*cda5da8dSAndroid Build Coastguard Worker 1344*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1345*cda5da8dSAndroid Build Coastguard Worker >>> screen.getshapes() 1346*cda5da8dSAndroid Build Coastguard Worker ['arrow', 'blank', 'circle', ... , 'turtle'] 1347*cda5da8dSAndroid Build Coastguard Worker """ 1348*cda5da8dSAndroid Build Coastguard Worker return sorted(self._shapes.keys()) 1349*cda5da8dSAndroid Build Coastguard Worker 1350*cda5da8dSAndroid Build Coastguard Worker def onclick(self, fun, btn=1, add=None): 1351*cda5da8dSAndroid Build Coastguard Worker """Bind fun to mouse-click event on canvas. 1352*cda5da8dSAndroid Build Coastguard Worker 1353*cda5da8dSAndroid Build Coastguard Worker Arguments: 1354*cda5da8dSAndroid Build Coastguard Worker fun -- a function with two arguments, the coordinates of the 1355*cda5da8dSAndroid Build Coastguard Worker clicked point on the canvas. 1356*cda5da8dSAndroid Build Coastguard Worker btn -- the number of the mouse-button, defaults to 1 1357*cda5da8dSAndroid Build Coastguard Worker 1358*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen) 1359*cda5da8dSAndroid Build Coastguard Worker 1360*cda5da8dSAndroid Build Coastguard Worker >>> screen.onclick(goto) 1361*cda5da8dSAndroid Build Coastguard Worker >>> # Subsequently clicking into the TurtleScreen will 1362*cda5da8dSAndroid Build Coastguard Worker >>> # make the turtle move to the clicked point. 1363*cda5da8dSAndroid Build Coastguard Worker >>> screen.onclick(None) 1364*cda5da8dSAndroid Build Coastguard Worker """ 1365*cda5da8dSAndroid Build Coastguard Worker self._onscreenclick(fun, btn, add) 1366*cda5da8dSAndroid Build Coastguard Worker 1367*cda5da8dSAndroid Build Coastguard Worker def onkey(self, fun, key): 1368*cda5da8dSAndroid Build Coastguard Worker """Bind fun to key-release event of key. 1369*cda5da8dSAndroid Build Coastguard Worker 1370*cda5da8dSAndroid Build Coastguard Worker Arguments: 1371*cda5da8dSAndroid Build Coastguard Worker fun -- a function with no arguments 1372*cda5da8dSAndroid Build Coastguard Worker key -- a string: key (e.g. "a") or key-symbol (e.g. "space") 1373*cda5da8dSAndroid Build Coastguard Worker 1374*cda5da8dSAndroid Build Coastguard Worker In order to be able to register key-events, TurtleScreen 1375*cda5da8dSAndroid Build Coastguard Worker must have focus. (See method listen.) 1376*cda5da8dSAndroid Build Coastguard Worker 1377*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1378*cda5da8dSAndroid Build Coastguard Worker 1379*cda5da8dSAndroid Build Coastguard Worker >>> def f(): 1380*cda5da8dSAndroid Build Coastguard Worker ... fd(50) 1381*cda5da8dSAndroid Build Coastguard Worker ... lt(60) 1382*cda5da8dSAndroid Build Coastguard Worker ... 1383*cda5da8dSAndroid Build Coastguard Worker >>> screen.onkey(f, "Up") 1384*cda5da8dSAndroid Build Coastguard Worker >>> screen.listen() 1385*cda5da8dSAndroid Build Coastguard Worker 1386*cda5da8dSAndroid Build Coastguard Worker Subsequently the turtle can be moved by repeatedly pressing 1387*cda5da8dSAndroid Build Coastguard Worker the up-arrow key, consequently drawing a hexagon 1388*cda5da8dSAndroid Build Coastguard Worker 1389*cda5da8dSAndroid Build Coastguard Worker """ 1390*cda5da8dSAndroid Build Coastguard Worker if fun is None: 1391*cda5da8dSAndroid Build Coastguard Worker if key in self._keys: 1392*cda5da8dSAndroid Build Coastguard Worker self._keys.remove(key) 1393*cda5da8dSAndroid Build Coastguard Worker elif key not in self._keys: 1394*cda5da8dSAndroid Build Coastguard Worker self._keys.append(key) 1395*cda5da8dSAndroid Build Coastguard Worker self._onkeyrelease(fun, key) 1396*cda5da8dSAndroid Build Coastguard Worker 1397*cda5da8dSAndroid Build Coastguard Worker def onkeypress(self, fun, key=None): 1398*cda5da8dSAndroid Build Coastguard Worker """Bind fun to key-press event of key if key is given, 1399*cda5da8dSAndroid Build Coastguard Worker or to any key-press-event if no key is given. 1400*cda5da8dSAndroid Build Coastguard Worker 1401*cda5da8dSAndroid Build Coastguard Worker Arguments: 1402*cda5da8dSAndroid Build Coastguard Worker fun -- a function with no arguments 1403*cda5da8dSAndroid Build Coastguard Worker key -- a string: key (e.g. "a") or key-symbol (e.g. "space") 1404*cda5da8dSAndroid Build Coastguard Worker 1405*cda5da8dSAndroid Build Coastguard Worker In order to be able to register key-events, TurtleScreen 1406*cda5da8dSAndroid Build Coastguard Worker must have focus. (See method listen.) 1407*cda5da8dSAndroid Build Coastguard Worker 1408*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen 1409*cda5da8dSAndroid Build Coastguard Worker and a Turtle instance named turtle): 1410*cda5da8dSAndroid Build Coastguard Worker 1411*cda5da8dSAndroid Build Coastguard Worker >>> def f(): 1412*cda5da8dSAndroid Build Coastguard Worker ... fd(50) 1413*cda5da8dSAndroid Build Coastguard Worker ... lt(60) 1414*cda5da8dSAndroid Build Coastguard Worker ... 1415*cda5da8dSAndroid Build Coastguard Worker >>> screen.onkeypress(f, "Up") 1416*cda5da8dSAndroid Build Coastguard Worker >>> screen.listen() 1417*cda5da8dSAndroid Build Coastguard Worker 1418*cda5da8dSAndroid Build Coastguard Worker Subsequently the turtle can be moved by repeatedly pressing 1419*cda5da8dSAndroid Build Coastguard Worker the up-arrow key, or by keeping pressed the up-arrow key. 1420*cda5da8dSAndroid Build Coastguard Worker consequently drawing a hexagon. 1421*cda5da8dSAndroid Build Coastguard Worker """ 1422*cda5da8dSAndroid Build Coastguard Worker if fun is None: 1423*cda5da8dSAndroid Build Coastguard Worker if key in self._keys: 1424*cda5da8dSAndroid Build Coastguard Worker self._keys.remove(key) 1425*cda5da8dSAndroid Build Coastguard Worker elif key is not None and key not in self._keys: 1426*cda5da8dSAndroid Build Coastguard Worker self._keys.append(key) 1427*cda5da8dSAndroid Build Coastguard Worker self._onkeypress(fun, key) 1428*cda5da8dSAndroid Build Coastguard Worker 1429*cda5da8dSAndroid Build Coastguard Worker def listen(self, xdummy=None, ydummy=None): 1430*cda5da8dSAndroid Build Coastguard Worker """Set focus on TurtleScreen (in order to collect key-events) 1431*cda5da8dSAndroid Build Coastguard Worker 1432*cda5da8dSAndroid Build Coastguard Worker No arguments. 1433*cda5da8dSAndroid Build Coastguard Worker Dummy arguments are provided in order 1434*cda5da8dSAndroid Build Coastguard Worker to be able to pass listen to the onclick method. 1435*cda5da8dSAndroid Build Coastguard Worker 1436*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1437*cda5da8dSAndroid Build Coastguard Worker >>> screen.listen() 1438*cda5da8dSAndroid Build Coastguard Worker """ 1439*cda5da8dSAndroid Build Coastguard Worker self._listen() 1440*cda5da8dSAndroid Build Coastguard Worker 1441*cda5da8dSAndroid Build Coastguard Worker def ontimer(self, fun, t=0): 1442*cda5da8dSAndroid Build Coastguard Worker """Install a timer, which calls fun after t milliseconds. 1443*cda5da8dSAndroid Build Coastguard Worker 1444*cda5da8dSAndroid Build Coastguard Worker Arguments: 1445*cda5da8dSAndroid Build Coastguard Worker fun -- a function with no arguments. 1446*cda5da8dSAndroid Build Coastguard Worker t -- a number >= 0 1447*cda5da8dSAndroid Build Coastguard Worker 1448*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1449*cda5da8dSAndroid Build Coastguard Worker 1450*cda5da8dSAndroid Build Coastguard Worker >>> running = True 1451*cda5da8dSAndroid Build Coastguard Worker >>> def f(): 1452*cda5da8dSAndroid Build Coastguard Worker ... if running: 1453*cda5da8dSAndroid Build Coastguard Worker ... fd(50) 1454*cda5da8dSAndroid Build Coastguard Worker ... lt(60) 1455*cda5da8dSAndroid Build Coastguard Worker ... screen.ontimer(f, 250) 1456*cda5da8dSAndroid Build Coastguard Worker ... 1457*cda5da8dSAndroid Build Coastguard Worker >>> f() # makes the turtle marching around 1458*cda5da8dSAndroid Build Coastguard Worker >>> running = False 1459*cda5da8dSAndroid Build Coastguard Worker """ 1460*cda5da8dSAndroid Build Coastguard Worker self._ontimer(fun, t) 1461*cda5da8dSAndroid Build Coastguard Worker 1462*cda5da8dSAndroid Build Coastguard Worker def bgpic(self, picname=None): 1463*cda5da8dSAndroid Build Coastguard Worker """Set background image or return name of current backgroundimage. 1464*cda5da8dSAndroid Build Coastguard Worker 1465*cda5da8dSAndroid Build Coastguard Worker Optional argument: 1466*cda5da8dSAndroid Build Coastguard Worker picname -- a string, name of a gif-file or "nopic". 1467*cda5da8dSAndroid Build Coastguard Worker 1468*cda5da8dSAndroid Build Coastguard Worker If picname is a filename, set the corresponding image as background. 1469*cda5da8dSAndroid Build Coastguard Worker If picname is "nopic", delete backgroundimage, if present. 1470*cda5da8dSAndroid Build Coastguard Worker If picname is None, return the filename of the current backgroundimage. 1471*cda5da8dSAndroid Build Coastguard Worker 1472*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 1473*cda5da8dSAndroid Build Coastguard Worker >>> screen.bgpic() 1474*cda5da8dSAndroid Build Coastguard Worker 'nopic' 1475*cda5da8dSAndroid Build Coastguard Worker >>> screen.bgpic("landscape.gif") 1476*cda5da8dSAndroid Build Coastguard Worker >>> screen.bgpic() 1477*cda5da8dSAndroid Build Coastguard Worker 'landscape.gif' 1478*cda5da8dSAndroid Build Coastguard Worker """ 1479*cda5da8dSAndroid Build Coastguard Worker if picname is None: 1480*cda5da8dSAndroid Build Coastguard Worker return self._bgpicname 1481*cda5da8dSAndroid Build Coastguard Worker if picname not in self._bgpics: 1482*cda5da8dSAndroid Build Coastguard Worker self._bgpics[picname] = self._image(picname) 1483*cda5da8dSAndroid Build Coastguard Worker self._setbgpic(self._bgpic, self._bgpics[picname]) 1484*cda5da8dSAndroid Build Coastguard Worker self._bgpicname = picname 1485*cda5da8dSAndroid Build Coastguard Worker 1486*cda5da8dSAndroid Build Coastguard Worker def screensize(self, canvwidth=None, canvheight=None, bg=None): 1487*cda5da8dSAndroid Build Coastguard Worker """Resize the canvas the turtles are drawing on. 1488*cda5da8dSAndroid Build Coastguard Worker 1489*cda5da8dSAndroid Build Coastguard Worker Optional arguments: 1490*cda5da8dSAndroid Build Coastguard Worker canvwidth -- positive integer, new width of canvas in pixels 1491*cda5da8dSAndroid Build Coastguard Worker canvheight -- positive integer, new height of canvas in pixels 1492*cda5da8dSAndroid Build Coastguard Worker bg -- colorstring or color-tuple, new backgroundcolor 1493*cda5da8dSAndroid Build Coastguard Worker If no arguments are given, return current (canvaswidth, canvasheight) 1494*cda5da8dSAndroid Build Coastguard Worker 1495*cda5da8dSAndroid Build Coastguard Worker Do not alter the drawing window. To observe hidden parts of 1496*cda5da8dSAndroid Build Coastguard Worker the canvas use the scrollbars. (Can make visible those parts 1497*cda5da8dSAndroid Build Coastguard Worker of a drawing, which were outside the canvas before!) 1498*cda5da8dSAndroid Build Coastguard Worker 1499*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1500*cda5da8dSAndroid Build Coastguard Worker >>> turtle.screensize(2000,1500) 1501*cda5da8dSAndroid Build Coastguard Worker >>> # e.g. to search for an erroneously escaped turtle ;-) 1502*cda5da8dSAndroid Build Coastguard Worker """ 1503*cda5da8dSAndroid Build Coastguard Worker return self._resize(canvwidth, canvheight, bg) 1504*cda5da8dSAndroid Build Coastguard Worker 1505*cda5da8dSAndroid Build Coastguard Worker onscreenclick = onclick 1506*cda5da8dSAndroid Build Coastguard Worker resetscreen = reset 1507*cda5da8dSAndroid Build Coastguard Worker clearscreen = clear 1508*cda5da8dSAndroid Build Coastguard Worker addshape = register_shape 1509*cda5da8dSAndroid Build Coastguard Worker onkeyrelease = onkey 1510*cda5da8dSAndroid Build Coastguard Worker 1511*cda5da8dSAndroid Build Coastguard Workerclass TNavigator(object): 1512*cda5da8dSAndroid Build Coastguard Worker """Navigation part of the RawTurtle. 1513*cda5da8dSAndroid Build Coastguard Worker Implements methods for turtle movement. 1514*cda5da8dSAndroid Build Coastguard Worker """ 1515*cda5da8dSAndroid Build Coastguard Worker START_ORIENTATION = { 1516*cda5da8dSAndroid Build Coastguard Worker "standard": Vec2D(1.0, 0.0), 1517*cda5da8dSAndroid Build Coastguard Worker "world" : Vec2D(1.0, 0.0), 1518*cda5da8dSAndroid Build Coastguard Worker "logo" : Vec2D(0.0, 1.0) } 1519*cda5da8dSAndroid Build Coastguard Worker DEFAULT_MODE = "standard" 1520*cda5da8dSAndroid Build Coastguard Worker DEFAULT_ANGLEOFFSET = 0 1521*cda5da8dSAndroid Build Coastguard Worker DEFAULT_ANGLEORIENT = 1 1522*cda5da8dSAndroid Build Coastguard Worker 1523*cda5da8dSAndroid Build Coastguard Worker def __init__(self, mode=DEFAULT_MODE): 1524*cda5da8dSAndroid Build Coastguard Worker self._angleOffset = self.DEFAULT_ANGLEOFFSET 1525*cda5da8dSAndroid Build Coastguard Worker self._angleOrient = self.DEFAULT_ANGLEORIENT 1526*cda5da8dSAndroid Build Coastguard Worker self._mode = mode 1527*cda5da8dSAndroid Build Coastguard Worker self.undobuffer = None 1528*cda5da8dSAndroid Build Coastguard Worker self.degrees() 1529*cda5da8dSAndroid Build Coastguard Worker self._mode = None 1530*cda5da8dSAndroid Build Coastguard Worker self._setmode(mode) 1531*cda5da8dSAndroid Build Coastguard Worker TNavigator.reset(self) 1532*cda5da8dSAndroid Build Coastguard Worker 1533*cda5da8dSAndroid Build Coastguard Worker def reset(self): 1534*cda5da8dSAndroid Build Coastguard Worker """reset turtle to its initial values 1535*cda5da8dSAndroid Build Coastguard Worker 1536*cda5da8dSAndroid Build Coastguard Worker Will be overwritten by parent class 1537*cda5da8dSAndroid Build Coastguard Worker """ 1538*cda5da8dSAndroid Build Coastguard Worker self._position = Vec2D(0.0, 0.0) 1539*cda5da8dSAndroid Build Coastguard Worker self._orient = TNavigator.START_ORIENTATION[self._mode] 1540*cda5da8dSAndroid Build Coastguard Worker 1541*cda5da8dSAndroid Build Coastguard Worker def _setmode(self, mode=None): 1542*cda5da8dSAndroid Build Coastguard Worker """Set turtle-mode to 'standard', 'world' or 'logo'. 1543*cda5da8dSAndroid Build Coastguard Worker """ 1544*cda5da8dSAndroid Build Coastguard Worker if mode is None: 1545*cda5da8dSAndroid Build Coastguard Worker return self._mode 1546*cda5da8dSAndroid Build Coastguard Worker if mode not in ["standard", "logo", "world"]: 1547*cda5da8dSAndroid Build Coastguard Worker return 1548*cda5da8dSAndroid Build Coastguard Worker self._mode = mode 1549*cda5da8dSAndroid Build Coastguard Worker if mode in ["standard", "world"]: 1550*cda5da8dSAndroid Build Coastguard Worker self._angleOffset = 0 1551*cda5da8dSAndroid Build Coastguard Worker self._angleOrient = 1 1552*cda5da8dSAndroid Build Coastguard Worker else: # mode == "logo": 1553*cda5da8dSAndroid Build Coastguard Worker self._angleOffset = self._fullcircle/4. 1554*cda5da8dSAndroid Build Coastguard Worker self._angleOrient = -1 1555*cda5da8dSAndroid Build Coastguard Worker 1556*cda5da8dSAndroid Build Coastguard Worker def _setDegreesPerAU(self, fullcircle): 1557*cda5da8dSAndroid Build Coastguard Worker """Helper function for degrees() and radians()""" 1558*cda5da8dSAndroid Build Coastguard Worker self._fullcircle = fullcircle 1559*cda5da8dSAndroid Build Coastguard Worker self._degreesPerAU = 360/fullcircle 1560*cda5da8dSAndroid Build Coastguard Worker if self._mode == "standard": 1561*cda5da8dSAndroid Build Coastguard Worker self._angleOffset = 0 1562*cda5da8dSAndroid Build Coastguard Worker else: 1563*cda5da8dSAndroid Build Coastguard Worker self._angleOffset = fullcircle/4. 1564*cda5da8dSAndroid Build Coastguard Worker 1565*cda5da8dSAndroid Build Coastguard Worker def degrees(self, fullcircle=360.0): 1566*cda5da8dSAndroid Build Coastguard Worker """ Set angle measurement units to degrees. 1567*cda5da8dSAndroid Build Coastguard Worker 1568*cda5da8dSAndroid Build Coastguard Worker Optional argument: 1569*cda5da8dSAndroid Build Coastguard Worker fullcircle - a number 1570*cda5da8dSAndroid Build Coastguard Worker 1571*cda5da8dSAndroid Build Coastguard Worker Set angle measurement units, i. e. set number 1572*cda5da8dSAndroid Build Coastguard Worker of 'degrees' for a full circle. Default value is 1573*cda5da8dSAndroid Build Coastguard Worker 360 degrees. 1574*cda5da8dSAndroid Build Coastguard Worker 1575*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1576*cda5da8dSAndroid Build Coastguard Worker >>> turtle.left(90) 1577*cda5da8dSAndroid Build Coastguard Worker >>> turtle.heading() 1578*cda5da8dSAndroid Build Coastguard Worker 90 1579*cda5da8dSAndroid Build Coastguard Worker 1580*cda5da8dSAndroid Build Coastguard Worker Change angle measurement unit to grad (also known as gon, 1581*cda5da8dSAndroid Build Coastguard Worker grade, or gradian and equals 1/100-th of the right angle.) 1582*cda5da8dSAndroid Build Coastguard Worker >>> turtle.degrees(400.0) 1583*cda5da8dSAndroid Build Coastguard Worker >>> turtle.heading() 1584*cda5da8dSAndroid Build Coastguard Worker 100 1585*cda5da8dSAndroid Build Coastguard Worker 1586*cda5da8dSAndroid Build Coastguard Worker """ 1587*cda5da8dSAndroid Build Coastguard Worker self._setDegreesPerAU(fullcircle) 1588*cda5da8dSAndroid Build Coastguard Worker 1589*cda5da8dSAndroid Build Coastguard Worker def radians(self): 1590*cda5da8dSAndroid Build Coastguard Worker """ Set the angle measurement units to radians. 1591*cda5da8dSAndroid Build Coastguard Worker 1592*cda5da8dSAndroid Build Coastguard Worker No arguments. 1593*cda5da8dSAndroid Build Coastguard Worker 1594*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1595*cda5da8dSAndroid Build Coastguard Worker >>> turtle.heading() 1596*cda5da8dSAndroid Build Coastguard Worker 90 1597*cda5da8dSAndroid Build Coastguard Worker >>> turtle.radians() 1598*cda5da8dSAndroid Build Coastguard Worker >>> turtle.heading() 1599*cda5da8dSAndroid Build Coastguard Worker 1.5707963267948966 1600*cda5da8dSAndroid Build Coastguard Worker """ 1601*cda5da8dSAndroid Build Coastguard Worker self._setDegreesPerAU(math.tau) 1602*cda5da8dSAndroid Build Coastguard Worker 1603*cda5da8dSAndroid Build Coastguard Worker def _go(self, distance): 1604*cda5da8dSAndroid Build Coastguard Worker """move turtle forward by specified distance""" 1605*cda5da8dSAndroid Build Coastguard Worker ende = self._position + self._orient * distance 1606*cda5da8dSAndroid Build Coastguard Worker self._goto(ende) 1607*cda5da8dSAndroid Build Coastguard Worker 1608*cda5da8dSAndroid Build Coastguard Worker def _rotate(self, angle): 1609*cda5da8dSAndroid Build Coastguard Worker """Turn turtle counterclockwise by specified angle if angle > 0.""" 1610*cda5da8dSAndroid Build Coastguard Worker angle *= self._degreesPerAU 1611*cda5da8dSAndroid Build Coastguard Worker self._orient = self._orient.rotate(angle) 1612*cda5da8dSAndroid Build Coastguard Worker 1613*cda5da8dSAndroid Build Coastguard Worker def _goto(self, end): 1614*cda5da8dSAndroid Build Coastguard Worker """move turtle to position end.""" 1615*cda5da8dSAndroid Build Coastguard Worker self._position = end 1616*cda5da8dSAndroid Build Coastguard Worker 1617*cda5da8dSAndroid Build Coastguard Worker def forward(self, distance): 1618*cda5da8dSAndroid Build Coastguard Worker """Move the turtle forward by the specified distance. 1619*cda5da8dSAndroid Build Coastguard Worker 1620*cda5da8dSAndroid Build Coastguard Worker Aliases: forward | fd 1621*cda5da8dSAndroid Build Coastguard Worker 1622*cda5da8dSAndroid Build Coastguard Worker Argument: 1623*cda5da8dSAndroid Build Coastguard Worker distance -- a number (integer or float) 1624*cda5da8dSAndroid Build Coastguard Worker 1625*cda5da8dSAndroid Build Coastguard Worker Move the turtle forward by the specified distance, in the direction 1626*cda5da8dSAndroid Build Coastguard Worker the turtle is headed. 1627*cda5da8dSAndroid Build Coastguard Worker 1628*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1629*cda5da8dSAndroid Build Coastguard Worker >>> turtle.position() 1630*cda5da8dSAndroid Build Coastguard Worker (0.00, 0.00) 1631*cda5da8dSAndroid Build Coastguard Worker >>> turtle.forward(25) 1632*cda5da8dSAndroid Build Coastguard Worker >>> turtle.position() 1633*cda5da8dSAndroid Build Coastguard Worker (25.00,0.00) 1634*cda5da8dSAndroid Build Coastguard Worker >>> turtle.forward(-75) 1635*cda5da8dSAndroid Build Coastguard Worker >>> turtle.position() 1636*cda5da8dSAndroid Build Coastguard Worker (-50.00,0.00) 1637*cda5da8dSAndroid Build Coastguard Worker """ 1638*cda5da8dSAndroid Build Coastguard Worker self._go(distance) 1639*cda5da8dSAndroid Build Coastguard Worker 1640*cda5da8dSAndroid Build Coastguard Worker def back(self, distance): 1641*cda5da8dSAndroid Build Coastguard Worker """Move the turtle backward by distance. 1642*cda5da8dSAndroid Build Coastguard Worker 1643*cda5da8dSAndroid Build Coastguard Worker Aliases: back | backward | bk 1644*cda5da8dSAndroid Build Coastguard Worker 1645*cda5da8dSAndroid Build Coastguard Worker Argument: 1646*cda5da8dSAndroid Build Coastguard Worker distance -- a number 1647*cda5da8dSAndroid Build Coastguard Worker 1648*cda5da8dSAndroid Build Coastguard Worker Move the turtle backward by distance, opposite to the direction the 1649*cda5da8dSAndroid Build Coastguard Worker turtle is headed. Do not change the turtle's heading. 1650*cda5da8dSAndroid Build Coastguard Worker 1651*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1652*cda5da8dSAndroid Build Coastguard Worker >>> turtle.position() 1653*cda5da8dSAndroid Build Coastguard Worker (0.00, 0.00) 1654*cda5da8dSAndroid Build Coastguard Worker >>> turtle.backward(30) 1655*cda5da8dSAndroid Build Coastguard Worker >>> turtle.position() 1656*cda5da8dSAndroid Build Coastguard Worker (-30.00, 0.00) 1657*cda5da8dSAndroid Build Coastguard Worker """ 1658*cda5da8dSAndroid Build Coastguard Worker self._go(-distance) 1659*cda5da8dSAndroid Build Coastguard Worker 1660*cda5da8dSAndroid Build Coastguard Worker def right(self, angle): 1661*cda5da8dSAndroid Build Coastguard Worker """Turn turtle right by angle units. 1662*cda5da8dSAndroid Build Coastguard Worker 1663*cda5da8dSAndroid Build Coastguard Worker Aliases: right | rt 1664*cda5da8dSAndroid Build Coastguard Worker 1665*cda5da8dSAndroid Build Coastguard Worker Argument: 1666*cda5da8dSAndroid Build Coastguard Worker angle -- a number (integer or float) 1667*cda5da8dSAndroid Build Coastguard Worker 1668*cda5da8dSAndroid Build Coastguard Worker Turn turtle right by angle units. (Units are by default degrees, 1669*cda5da8dSAndroid Build Coastguard Worker but can be set via the degrees() and radians() functions.) 1670*cda5da8dSAndroid Build Coastguard Worker Angle orientation depends on mode. (See this.) 1671*cda5da8dSAndroid Build Coastguard Worker 1672*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1673*cda5da8dSAndroid Build Coastguard Worker >>> turtle.heading() 1674*cda5da8dSAndroid Build Coastguard Worker 22.0 1675*cda5da8dSAndroid Build Coastguard Worker >>> turtle.right(45) 1676*cda5da8dSAndroid Build Coastguard Worker >>> turtle.heading() 1677*cda5da8dSAndroid Build Coastguard Worker 337.0 1678*cda5da8dSAndroid Build Coastguard Worker """ 1679*cda5da8dSAndroid Build Coastguard Worker self._rotate(-angle) 1680*cda5da8dSAndroid Build Coastguard Worker 1681*cda5da8dSAndroid Build Coastguard Worker def left(self, angle): 1682*cda5da8dSAndroid Build Coastguard Worker """Turn turtle left by angle units. 1683*cda5da8dSAndroid Build Coastguard Worker 1684*cda5da8dSAndroid Build Coastguard Worker Aliases: left | lt 1685*cda5da8dSAndroid Build Coastguard Worker 1686*cda5da8dSAndroid Build Coastguard Worker Argument: 1687*cda5da8dSAndroid Build Coastguard Worker angle -- a number (integer or float) 1688*cda5da8dSAndroid Build Coastguard Worker 1689*cda5da8dSAndroid Build Coastguard Worker Turn turtle left by angle units. (Units are by default degrees, 1690*cda5da8dSAndroid Build Coastguard Worker but can be set via the degrees() and radians() functions.) 1691*cda5da8dSAndroid Build Coastguard Worker Angle orientation depends on mode. (See this.) 1692*cda5da8dSAndroid Build Coastguard Worker 1693*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1694*cda5da8dSAndroid Build Coastguard Worker >>> turtle.heading() 1695*cda5da8dSAndroid Build Coastguard Worker 22.0 1696*cda5da8dSAndroid Build Coastguard Worker >>> turtle.left(45) 1697*cda5da8dSAndroid Build Coastguard Worker >>> turtle.heading() 1698*cda5da8dSAndroid Build Coastguard Worker 67.0 1699*cda5da8dSAndroid Build Coastguard Worker """ 1700*cda5da8dSAndroid Build Coastguard Worker self._rotate(angle) 1701*cda5da8dSAndroid Build Coastguard Worker 1702*cda5da8dSAndroid Build Coastguard Worker def pos(self): 1703*cda5da8dSAndroid Build Coastguard Worker """Return the turtle's current location (x,y), as a Vec2D-vector. 1704*cda5da8dSAndroid Build Coastguard Worker 1705*cda5da8dSAndroid Build Coastguard Worker Aliases: pos | position 1706*cda5da8dSAndroid Build Coastguard Worker 1707*cda5da8dSAndroid Build Coastguard Worker No arguments. 1708*cda5da8dSAndroid Build Coastguard Worker 1709*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1710*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pos() 1711*cda5da8dSAndroid Build Coastguard Worker (0.00, 240.00) 1712*cda5da8dSAndroid Build Coastguard Worker """ 1713*cda5da8dSAndroid Build Coastguard Worker return self._position 1714*cda5da8dSAndroid Build Coastguard Worker 1715*cda5da8dSAndroid Build Coastguard Worker def xcor(self): 1716*cda5da8dSAndroid Build Coastguard Worker """ Return the turtle's x coordinate. 1717*cda5da8dSAndroid Build Coastguard Worker 1718*cda5da8dSAndroid Build Coastguard Worker No arguments. 1719*cda5da8dSAndroid Build Coastguard Worker 1720*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1721*cda5da8dSAndroid Build Coastguard Worker >>> reset() 1722*cda5da8dSAndroid Build Coastguard Worker >>> turtle.left(60) 1723*cda5da8dSAndroid Build Coastguard Worker >>> turtle.forward(100) 1724*cda5da8dSAndroid Build Coastguard Worker >>> print turtle.xcor() 1725*cda5da8dSAndroid Build Coastguard Worker 50.0 1726*cda5da8dSAndroid Build Coastguard Worker """ 1727*cda5da8dSAndroid Build Coastguard Worker return self._position[0] 1728*cda5da8dSAndroid Build Coastguard Worker 1729*cda5da8dSAndroid Build Coastguard Worker def ycor(self): 1730*cda5da8dSAndroid Build Coastguard Worker """ Return the turtle's y coordinate 1731*cda5da8dSAndroid Build Coastguard Worker --- 1732*cda5da8dSAndroid Build Coastguard Worker No arguments. 1733*cda5da8dSAndroid Build Coastguard Worker 1734*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1735*cda5da8dSAndroid Build Coastguard Worker >>> reset() 1736*cda5da8dSAndroid Build Coastguard Worker >>> turtle.left(60) 1737*cda5da8dSAndroid Build Coastguard Worker >>> turtle.forward(100) 1738*cda5da8dSAndroid Build Coastguard Worker >>> print turtle.ycor() 1739*cda5da8dSAndroid Build Coastguard Worker 86.6025403784 1740*cda5da8dSAndroid Build Coastguard Worker """ 1741*cda5da8dSAndroid Build Coastguard Worker return self._position[1] 1742*cda5da8dSAndroid Build Coastguard Worker 1743*cda5da8dSAndroid Build Coastguard Worker 1744*cda5da8dSAndroid Build Coastguard Worker def goto(self, x, y=None): 1745*cda5da8dSAndroid Build Coastguard Worker """Move turtle to an absolute position. 1746*cda5da8dSAndroid Build Coastguard Worker 1747*cda5da8dSAndroid Build Coastguard Worker Aliases: setpos | setposition | goto: 1748*cda5da8dSAndroid Build Coastguard Worker 1749*cda5da8dSAndroid Build Coastguard Worker Arguments: 1750*cda5da8dSAndroid Build Coastguard Worker x -- a number or a pair/vector of numbers 1751*cda5da8dSAndroid Build Coastguard Worker y -- a number None 1752*cda5da8dSAndroid Build Coastguard Worker 1753*cda5da8dSAndroid Build Coastguard Worker call: goto(x, y) # two coordinates 1754*cda5da8dSAndroid Build Coastguard Worker --or: goto((x, y)) # a pair (tuple) of coordinates 1755*cda5da8dSAndroid Build Coastguard Worker --or: goto(vec) # e.g. as returned by pos() 1756*cda5da8dSAndroid Build Coastguard Worker 1757*cda5da8dSAndroid Build Coastguard Worker Move turtle to an absolute position. If the pen is down, 1758*cda5da8dSAndroid Build Coastguard Worker a line will be drawn. The turtle's orientation does not change. 1759*cda5da8dSAndroid Build Coastguard Worker 1760*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1761*cda5da8dSAndroid Build Coastguard Worker >>> tp = turtle.pos() 1762*cda5da8dSAndroid Build Coastguard Worker >>> tp 1763*cda5da8dSAndroid Build Coastguard Worker (0.00, 0.00) 1764*cda5da8dSAndroid Build Coastguard Worker >>> turtle.setpos(60,30) 1765*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pos() 1766*cda5da8dSAndroid Build Coastguard Worker (60.00,30.00) 1767*cda5da8dSAndroid Build Coastguard Worker >>> turtle.setpos((20,80)) 1768*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pos() 1769*cda5da8dSAndroid Build Coastguard Worker (20.00,80.00) 1770*cda5da8dSAndroid Build Coastguard Worker >>> turtle.setpos(tp) 1771*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pos() 1772*cda5da8dSAndroid Build Coastguard Worker (0.00,0.00) 1773*cda5da8dSAndroid Build Coastguard Worker """ 1774*cda5da8dSAndroid Build Coastguard Worker if y is None: 1775*cda5da8dSAndroid Build Coastguard Worker self._goto(Vec2D(*x)) 1776*cda5da8dSAndroid Build Coastguard Worker else: 1777*cda5da8dSAndroid Build Coastguard Worker self._goto(Vec2D(x, y)) 1778*cda5da8dSAndroid Build Coastguard Worker 1779*cda5da8dSAndroid Build Coastguard Worker def home(self): 1780*cda5da8dSAndroid Build Coastguard Worker """Move turtle to the origin - coordinates (0,0). 1781*cda5da8dSAndroid Build Coastguard Worker 1782*cda5da8dSAndroid Build Coastguard Worker No arguments. 1783*cda5da8dSAndroid Build Coastguard Worker 1784*cda5da8dSAndroid Build Coastguard Worker Move turtle to the origin - coordinates (0,0) and set its 1785*cda5da8dSAndroid Build Coastguard Worker heading to its start-orientation (which depends on mode). 1786*cda5da8dSAndroid Build Coastguard Worker 1787*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1788*cda5da8dSAndroid Build Coastguard Worker >>> turtle.home() 1789*cda5da8dSAndroid Build Coastguard Worker """ 1790*cda5da8dSAndroid Build Coastguard Worker self.goto(0, 0) 1791*cda5da8dSAndroid Build Coastguard Worker self.setheading(0) 1792*cda5da8dSAndroid Build Coastguard Worker 1793*cda5da8dSAndroid Build Coastguard Worker def setx(self, x): 1794*cda5da8dSAndroid Build Coastguard Worker """Set the turtle's first coordinate to x 1795*cda5da8dSAndroid Build Coastguard Worker 1796*cda5da8dSAndroid Build Coastguard Worker Argument: 1797*cda5da8dSAndroid Build Coastguard Worker x -- a number (integer or float) 1798*cda5da8dSAndroid Build Coastguard Worker 1799*cda5da8dSAndroid Build Coastguard Worker Set the turtle's first coordinate to x, leave second coordinate 1800*cda5da8dSAndroid Build Coastguard Worker unchanged. 1801*cda5da8dSAndroid Build Coastguard Worker 1802*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1803*cda5da8dSAndroid Build Coastguard Worker >>> turtle.position() 1804*cda5da8dSAndroid Build Coastguard Worker (0.00, 240.00) 1805*cda5da8dSAndroid Build Coastguard Worker >>> turtle.setx(10) 1806*cda5da8dSAndroid Build Coastguard Worker >>> turtle.position() 1807*cda5da8dSAndroid Build Coastguard Worker (10.00, 240.00) 1808*cda5da8dSAndroid Build Coastguard Worker """ 1809*cda5da8dSAndroid Build Coastguard Worker self._goto(Vec2D(x, self._position[1])) 1810*cda5da8dSAndroid Build Coastguard Worker 1811*cda5da8dSAndroid Build Coastguard Worker def sety(self, y): 1812*cda5da8dSAndroid Build Coastguard Worker """Set the turtle's second coordinate to y 1813*cda5da8dSAndroid Build Coastguard Worker 1814*cda5da8dSAndroid Build Coastguard Worker Argument: 1815*cda5da8dSAndroid Build Coastguard Worker y -- a number (integer or float) 1816*cda5da8dSAndroid Build Coastguard Worker 1817*cda5da8dSAndroid Build Coastguard Worker Set the turtle's first coordinate to x, second coordinate remains 1818*cda5da8dSAndroid Build Coastguard Worker unchanged. 1819*cda5da8dSAndroid Build Coastguard Worker 1820*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1821*cda5da8dSAndroid Build Coastguard Worker >>> turtle.position() 1822*cda5da8dSAndroid Build Coastguard Worker (0.00, 40.00) 1823*cda5da8dSAndroid Build Coastguard Worker >>> turtle.sety(-10) 1824*cda5da8dSAndroid Build Coastguard Worker >>> turtle.position() 1825*cda5da8dSAndroid Build Coastguard Worker (0.00, -10.00) 1826*cda5da8dSAndroid Build Coastguard Worker """ 1827*cda5da8dSAndroid Build Coastguard Worker self._goto(Vec2D(self._position[0], y)) 1828*cda5da8dSAndroid Build Coastguard Worker 1829*cda5da8dSAndroid Build Coastguard Worker def distance(self, x, y=None): 1830*cda5da8dSAndroid Build Coastguard Worker """Return the distance from the turtle to (x,y) in turtle step units. 1831*cda5da8dSAndroid Build Coastguard Worker 1832*cda5da8dSAndroid Build Coastguard Worker Arguments: 1833*cda5da8dSAndroid Build Coastguard Worker x -- a number or a pair/vector of numbers or a turtle instance 1834*cda5da8dSAndroid Build Coastguard Worker y -- a number None None 1835*cda5da8dSAndroid Build Coastguard Worker 1836*cda5da8dSAndroid Build Coastguard Worker call: distance(x, y) # two coordinates 1837*cda5da8dSAndroid Build Coastguard Worker --or: distance((x, y)) # a pair (tuple) of coordinates 1838*cda5da8dSAndroid Build Coastguard Worker --or: distance(vec) # e.g. as returned by pos() 1839*cda5da8dSAndroid Build Coastguard Worker --or: distance(mypen) # where mypen is another turtle 1840*cda5da8dSAndroid Build Coastguard Worker 1841*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1842*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pos() 1843*cda5da8dSAndroid Build Coastguard Worker (0.00, 0.00) 1844*cda5da8dSAndroid Build Coastguard Worker >>> turtle.distance(30,40) 1845*cda5da8dSAndroid Build Coastguard Worker 50.0 1846*cda5da8dSAndroid Build Coastguard Worker >>> pen = Turtle() 1847*cda5da8dSAndroid Build Coastguard Worker >>> pen.forward(77) 1848*cda5da8dSAndroid Build Coastguard Worker >>> turtle.distance(pen) 1849*cda5da8dSAndroid Build Coastguard Worker 77.0 1850*cda5da8dSAndroid Build Coastguard Worker """ 1851*cda5da8dSAndroid Build Coastguard Worker if y is not None: 1852*cda5da8dSAndroid Build Coastguard Worker pos = Vec2D(x, y) 1853*cda5da8dSAndroid Build Coastguard Worker if isinstance(x, Vec2D): 1854*cda5da8dSAndroid Build Coastguard Worker pos = x 1855*cda5da8dSAndroid Build Coastguard Worker elif isinstance(x, tuple): 1856*cda5da8dSAndroid Build Coastguard Worker pos = Vec2D(*x) 1857*cda5da8dSAndroid Build Coastguard Worker elif isinstance(x, TNavigator): 1858*cda5da8dSAndroid Build Coastguard Worker pos = x._position 1859*cda5da8dSAndroid Build Coastguard Worker return abs(pos - self._position) 1860*cda5da8dSAndroid Build Coastguard Worker 1861*cda5da8dSAndroid Build Coastguard Worker def towards(self, x, y=None): 1862*cda5da8dSAndroid Build Coastguard Worker """Return the angle of the line from the turtle's position to (x, y). 1863*cda5da8dSAndroid Build Coastguard Worker 1864*cda5da8dSAndroid Build Coastguard Worker Arguments: 1865*cda5da8dSAndroid Build Coastguard Worker x -- a number or a pair/vector of numbers or a turtle instance 1866*cda5da8dSAndroid Build Coastguard Worker y -- a number None None 1867*cda5da8dSAndroid Build Coastguard Worker 1868*cda5da8dSAndroid Build Coastguard Worker call: distance(x, y) # two coordinates 1869*cda5da8dSAndroid Build Coastguard Worker --or: distance((x, y)) # a pair (tuple) of coordinates 1870*cda5da8dSAndroid Build Coastguard Worker --or: distance(vec) # e.g. as returned by pos() 1871*cda5da8dSAndroid Build Coastguard Worker --or: distance(mypen) # where mypen is another turtle 1872*cda5da8dSAndroid Build Coastguard Worker 1873*cda5da8dSAndroid Build Coastguard Worker Return the angle, between the line from turtle-position to position 1874*cda5da8dSAndroid Build Coastguard Worker specified by x, y and the turtle's start orientation. (Depends on 1875*cda5da8dSAndroid Build Coastguard Worker modes - "standard" or "logo") 1876*cda5da8dSAndroid Build Coastguard Worker 1877*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1878*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pos() 1879*cda5da8dSAndroid Build Coastguard Worker (10.00, 10.00) 1880*cda5da8dSAndroid Build Coastguard Worker >>> turtle.towards(0,0) 1881*cda5da8dSAndroid Build Coastguard Worker 225.0 1882*cda5da8dSAndroid Build Coastguard Worker """ 1883*cda5da8dSAndroid Build Coastguard Worker if y is not None: 1884*cda5da8dSAndroid Build Coastguard Worker pos = Vec2D(x, y) 1885*cda5da8dSAndroid Build Coastguard Worker if isinstance(x, Vec2D): 1886*cda5da8dSAndroid Build Coastguard Worker pos = x 1887*cda5da8dSAndroid Build Coastguard Worker elif isinstance(x, tuple): 1888*cda5da8dSAndroid Build Coastguard Worker pos = Vec2D(*x) 1889*cda5da8dSAndroid Build Coastguard Worker elif isinstance(x, TNavigator): 1890*cda5da8dSAndroid Build Coastguard Worker pos = x._position 1891*cda5da8dSAndroid Build Coastguard Worker x, y = pos - self._position 1892*cda5da8dSAndroid Build Coastguard Worker result = round(math.degrees(math.atan2(y, x)), 10) % 360.0 1893*cda5da8dSAndroid Build Coastguard Worker result /= self._degreesPerAU 1894*cda5da8dSAndroid Build Coastguard Worker return (self._angleOffset + self._angleOrient*result) % self._fullcircle 1895*cda5da8dSAndroid Build Coastguard Worker 1896*cda5da8dSAndroid Build Coastguard Worker def heading(self): 1897*cda5da8dSAndroid Build Coastguard Worker """ Return the turtle's current heading. 1898*cda5da8dSAndroid Build Coastguard Worker 1899*cda5da8dSAndroid Build Coastguard Worker No arguments. 1900*cda5da8dSAndroid Build Coastguard Worker 1901*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1902*cda5da8dSAndroid Build Coastguard Worker >>> turtle.left(67) 1903*cda5da8dSAndroid Build Coastguard Worker >>> turtle.heading() 1904*cda5da8dSAndroid Build Coastguard Worker 67.0 1905*cda5da8dSAndroid Build Coastguard Worker """ 1906*cda5da8dSAndroid Build Coastguard Worker x, y = self._orient 1907*cda5da8dSAndroid Build Coastguard Worker result = round(math.degrees(math.atan2(y, x)), 10) % 360.0 1908*cda5da8dSAndroid Build Coastguard Worker result /= self._degreesPerAU 1909*cda5da8dSAndroid Build Coastguard Worker return (self._angleOffset + self._angleOrient*result) % self._fullcircle 1910*cda5da8dSAndroid Build Coastguard Worker 1911*cda5da8dSAndroid Build Coastguard Worker def setheading(self, to_angle): 1912*cda5da8dSAndroid Build Coastguard Worker """Set the orientation of the turtle to to_angle. 1913*cda5da8dSAndroid Build Coastguard Worker 1914*cda5da8dSAndroid Build Coastguard Worker Aliases: setheading | seth 1915*cda5da8dSAndroid Build Coastguard Worker 1916*cda5da8dSAndroid Build Coastguard Worker Argument: 1917*cda5da8dSAndroid Build Coastguard Worker to_angle -- a number (integer or float) 1918*cda5da8dSAndroid Build Coastguard Worker 1919*cda5da8dSAndroid Build Coastguard Worker Set the orientation of the turtle to to_angle. 1920*cda5da8dSAndroid Build Coastguard Worker Here are some common directions in degrees: 1921*cda5da8dSAndroid Build Coastguard Worker 1922*cda5da8dSAndroid Build Coastguard Worker standard - mode: logo-mode: 1923*cda5da8dSAndroid Build Coastguard Worker -------------------|-------------------- 1924*cda5da8dSAndroid Build Coastguard Worker 0 - east 0 - north 1925*cda5da8dSAndroid Build Coastguard Worker 90 - north 90 - east 1926*cda5da8dSAndroid Build Coastguard Worker 180 - west 180 - south 1927*cda5da8dSAndroid Build Coastguard Worker 270 - south 270 - west 1928*cda5da8dSAndroid Build Coastguard Worker 1929*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1930*cda5da8dSAndroid Build Coastguard Worker >>> turtle.setheading(90) 1931*cda5da8dSAndroid Build Coastguard Worker >>> turtle.heading() 1932*cda5da8dSAndroid Build Coastguard Worker 90 1933*cda5da8dSAndroid Build Coastguard Worker """ 1934*cda5da8dSAndroid Build Coastguard Worker angle = (to_angle - self.heading())*self._angleOrient 1935*cda5da8dSAndroid Build Coastguard Worker full = self._fullcircle 1936*cda5da8dSAndroid Build Coastguard Worker angle = (angle+full/2.)%full - full/2. 1937*cda5da8dSAndroid Build Coastguard Worker self._rotate(angle) 1938*cda5da8dSAndroid Build Coastguard Worker 1939*cda5da8dSAndroid Build Coastguard Worker def circle(self, radius, extent = None, steps = None): 1940*cda5da8dSAndroid Build Coastguard Worker """ Draw a circle with given radius. 1941*cda5da8dSAndroid Build Coastguard Worker 1942*cda5da8dSAndroid Build Coastguard Worker Arguments: 1943*cda5da8dSAndroid Build Coastguard Worker radius -- a number 1944*cda5da8dSAndroid Build Coastguard Worker extent (optional) -- a number 1945*cda5da8dSAndroid Build Coastguard Worker steps (optional) -- an integer 1946*cda5da8dSAndroid Build Coastguard Worker 1947*cda5da8dSAndroid Build Coastguard Worker Draw a circle with given radius. The center is radius units left 1948*cda5da8dSAndroid Build Coastguard Worker of the turtle; extent - an angle - determines which part of the 1949*cda5da8dSAndroid Build Coastguard Worker circle is drawn. If extent is not given, draw the entire circle. 1950*cda5da8dSAndroid Build Coastguard Worker If extent is not a full circle, one endpoint of the arc is the 1951*cda5da8dSAndroid Build Coastguard Worker current pen position. Draw the arc in counterclockwise direction 1952*cda5da8dSAndroid Build Coastguard Worker if radius is positive, otherwise in clockwise direction. Finally 1953*cda5da8dSAndroid Build Coastguard Worker the direction of the turtle is changed by the amount of extent. 1954*cda5da8dSAndroid Build Coastguard Worker 1955*cda5da8dSAndroid Build Coastguard Worker As the circle is approximated by an inscribed regular polygon, 1956*cda5da8dSAndroid Build Coastguard Worker steps determines the number of steps to use. If not given, 1957*cda5da8dSAndroid Build Coastguard Worker it will be calculated automatically. Maybe used to draw regular 1958*cda5da8dSAndroid Build Coastguard Worker polygons. 1959*cda5da8dSAndroid Build Coastguard Worker 1960*cda5da8dSAndroid Build Coastguard Worker call: circle(radius) # full circle 1961*cda5da8dSAndroid Build Coastguard Worker --or: circle(radius, extent) # arc 1962*cda5da8dSAndroid Build Coastguard Worker --or: circle(radius, extent, steps) 1963*cda5da8dSAndroid Build Coastguard Worker --or: circle(radius, steps=6) # 6-sided polygon 1964*cda5da8dSAndroid Build Coastguard Worker 1965*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 1966*cda5da8dSAndroid Build Coastguard Worker >>> turtle.circle(50) 1967*cda5da8dSAndroid Build Coastguard Worker >>> turtle.circle(120, 180) # semicircle 1968*cda5da8dSAndroid Build Coastguard Worker """ 1969*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer: 1970*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.push(["seq"]) 1971*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.cumulate = True 1972*cda5da8dSAndroid Build Coastguard Worker speed = self.speed() 1973*cda5da8dSAndroid Build Coastguard Worker if extent is None: 1974*cda5da8dSAndroid Build Coastguard Worker extent = self._fullcircle 1975*cda5da8dSAndroid Build Coastguard Worker if steps is None: 1976*cda5da8dSAndroid Build Coastguard Worker frac = abs(extent)/self._fullcircle 1977*cda5da8dSAndroid Build Coastguard Worker steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac) 1978*cda5da8dSAndroid Build Coastguard Worker w = 1.0 * extent / steps 1979*cda5da8dSAndroid Build Coastguard Worker w2 = 0.5 * w 1980*cda5da8dSAndroid Build Coastguard Worker l = 2.0 * radius * math.sin(math.radians(w2)*self._degreesPerAU) 1981*cda5da8dSAndroid Build Coastguard Worker if radius < 0: 1982*cda5da8dSAndroid Build Coastguard Worker l, w, w2 = -l, -w, -w2 1983*cda5da8dSAndroid Build Coastguard Worker tr = self._tracer() 1984*cda5da8dSAndroid Build Coastguard Worker dl = self._delay() 1985*cda5da8dSAndroid Build Coastguard Worker if speed == 0: 1986*cda5da8dSAndroid Build Coastguard Worker self._tracer(0, 0) 1987*cda5da8dSAndroid Build Coastguard Worker else: 1988*cda5da8dSAndroid Build Coastguard Worker self.speed(0) 1989*cda5da8dSAndroid Build Coastguard Worker self._rotate(w2) 1990*cda5da8dSAndroid Build Coastguard Worker for i in range(steps): 1991*cda5da8dSAndroid Build Coastguard Worker self.speed(speed) 1992*cda5da8dSAndroid Build Coastguard Worker self._go(l) 1993*cda5da8dSAndroid Build Coastguard Worker self.speed(0) 1994*cda5da8dSAndroid Build Coastguard Worker self._rotate(w) 1995*cda5da8dSAndroid Build Coastguard Worker self._rotate(-w2) 1996*cda5da8dSAndroid Build Coastguard Worker if speed == 0: 1997*cda5da8dSAndroid Build Coastguard Worker self._tracer(tr, dl) 1998*cda5da8dSAndroid Build Coastguard Worker self.speed(speed) 1999*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer: 2000*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.cumulate = False 2001*cda5da8dSAndroid Build Coastguard Worker 2002*cda5da8dSAndroid Build Coastguard Worker## three dummy methods to be implemented by child class: 2003*cda5da8dSAndroid Build Coastguard Worker 2004*cda5da8dSAndroid Build Coastguard Worker def speed(self, s=0): 2005*cda5da8dSAndroid Build Coastguard Worker """dummy method - to be overwritten by child class""" 2006*cda5da8dSAndroid Build Coastguard Worker def _tracer(self, a=None, b=None): 2007*cda5da8dSAndroid Build Coastguard Worker """dummy method - to be overwritten by child class""" 2008*cda5da8dSAndroid Build Coastguard Worker def _delay(self, n=None): 2009*cda5da8dSAndroid Build Coastguard Worker """dummy method - to be overwritten by child class""" 2010*cda5da8dSAndroid Build Coastguard Worker 2011*cda5da8dSAndroid Build Coastguard Worker fd = forward 2012*cda5da8dSAndroid Build Coastguard Worker bk = back 2013*cda5da8dSAndroid Build Coastguard Worker backward = back 2014*cda5da8dSAndroid Build Coastguard Worker rt = right 2015*cda5da8dSAndroid Build Coastguard Worker lt = left 2016*cda5da8dSAndroid Build Coastguard Worker position = pos 2017*cda5da8dSAndroid Build Coastguard Worker setpos = goto 2018*cda5da8dSAndroid Build Coastguard Worker setposition = goto 2019*cda5da8dSAndroid Build Coastguard Worker seth = setheading 2020*cda5da8dSAndroid Build Coastguard Worker 2021*cda5da8dSAndroid Build Coastguard Worker 2022*cda5da8dSAndroid Build Coastguard Workerclass TPen(object): 2023*cda5da8dSAndroid Build Coastguard Worker """Drawing part of the RawTurtle. 2024*cda5da8dSAndroid Build Coastguard Worker Implements drawing properties. 2025*cda5da8dSAndroid Build Coastguard Worker """ 2026*cda5da8dSAndroid Build Coastguard Worker def __init__(self, resizemode=_CFG["resizemode"]): 2027*cda5da8dSAndroid Build Coastguard Worker self._resizemode = resizemode # or "user" or "noresize" 2028*cda5da8dSAndroid Build Coastguard Worker self.undobuffer = None 2029*cda5da8dSAndroid Build Coastguard Worker TPen._reset(self) 2030*cda5da8dSAndroid Build Coastguard Worker 2031*cda5da8dSAndroid Build Coastguard Worker def _reset(self, pencolor=_CFG["pencolor"], 2032*cda5da8dSAndroid Build Coastguard Worker fillcolor=_CFG["fillcolor"]): 2033*cda5da8dSAndroid Build Coastguard Worker self._pensize = 1 2034*cda5da8dSAndroid Build Coastguard Worker self._shown = True 2035*cda5da8dSAndroid Build Coastguard Worker self._pencolor = pencolor 2036*cda5da8dSAndroid Build Coastguard Worker self._fillcolor = fillcolor 2037*cda5da8dSAndroid Build Coastguard Worker self._drawing = True 2038*cda5da8dSAndroid Build Coastguard Worker self._speed = 3 2039*cda5da8dSAndroid Build Coastguard Worker self._stretchfactor = (1., 1.) 2040*cda5da8dSAndroid Build Coastguard Worker self._shearfactor = 0. 2041*cda5da8dSAndroid Build Coastguard Worker self._tilt = 0. 2042*cda5da8dSAndroid Build Coastguard Worker self._shapetrafo = (1., 0., 0., 1.) 2043*cda5da8dSAndroid Build Coastguard Worker self._outlinewidth = 1 2044*cda5da8dSAndroid Build Coastguard Worker 2045*cda5da8dSAndroid Build Coastguard Worker def resizemode(self, rmode=None): 2046*cda5da8dSAndroid Build Coastguard Worker """Set resizemode to one of the values: "auto", "user", "noresize". 2047*cda5da8dSAndroid Build Coastguard Worker 2048*cda5da8dSAndroid Build Coastguard Worker (Optional) Argument: 2049*cda5da8dSAndroid Build Coastguard Worker rmode -- one of the strings "auto", "user", "noresize" 2050*cda5da8dSAndroid Build Coastguard Worker 2051*cda5da8dSAndroid Build Coastguard Worker Different resizemodes have the following effects: 2052*cda5da8dSAndroid Build Coastguard Worker - "auto" adapts the appearance of the turtle 2053*cda5da8dSAndroid Build Coastguard Worker corresponding to the value of pensize. 2054*cda5da8dSAndroid Build Coastguard Worker - "user" adapts the appearance of the turtle according to the 2055*cda5da8dSAndroid Build Coastguard Worker values of stretchfactor and outlinewidth (outline), 2056*cda5da8dSAndroid Build Coastguard Worker which are set by shapesize() 2057*cda5da8dSAndroid Build Coastguard Worker - "noresize" no adaption of the turtle's appearance takes place. 2058*cda5da8dSAndroid Build Coastguard Worker If no argument is given, return current resizemode. 2059*cda5da8dSAndroid Build Coastguard Worker resizemode("user") is called by a call of shapesize with arguments. 2060*cda5da8dSAndroid Build Coastguard Worker 2061*cda5da8dSAndroid Build Coastguard Worker 2062*cda5da8dSAndroid Build Coastguard Worker Examples (for a Turtle instance named turtle): 2063*cda5da8dSAndroid Build Coastguard Worker >>> turtle.resizemode("noresize") 2064*cda5da8dSAndroid Build Coastguard Worker >>> turtle.resizemode() 2065*cda5da8dSAndroid Build Coastguard Worker 'noresize' 2066*cda5da8dSAndroid Build Coastguard Worker """ 2067*cda5da8dSAndroid Build Coastguard Worker if rmode is None: 2068*cda5da8dSAndroid Build Coastguard Worker return self._resizemode 2069*cda5da8dSAndroid Build Coastguard Worker rmode = rmode.lower() 2070*cda5da8dSAndroid Build Coastguard Worker if rmode in ["auto", "user", "noresize"]: 2071*cda5da8dSAndroid Build Coastguard Worker self.pen(resizemode=rmode) 2072*cda5da8dSAndroid Build Coastguard Worker 2073*cda5da8dSAndroid Build Coastguard Worker def pensize(self, width=None): 2074*cda5da8dSAndroid Build Coastguard Worker """Set or return the line thickness. 2075*cda5da8dSAndroid Build Coastguard Worker 2076*cda5da8dSAndroid Build Coastguard Worker Aliases: pensize | width 2077*cda5da8dSAndroid Build Coastguard Worker 2078*cda5da8dSAndroid Build Coastguard Worker Argument: 2079*cda5da8dSAndroid Build Coastguard Worker width -- positive number 2080*cda5da8dSAndroid Build Coastguard Worker 2081*cda5da8dSAndroid Build Coastguard Worker Set the line thickness to width or return it. If resizemode is set 2082*cda5da8dSAndroid Build Coastguard Worker to "auto" and turtleshape is a polygon, that polygon is drawn with 2083*cda5da8dSAndroid Build Coastguard Worker the same line thickness. If no argument is given, current pensize 2084*cda5da8dSAndroid Build Coastguard Worker is returned. 2085*cda5da8dSAndroid Build Coastguard Worker 2086*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2087*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pensize() 2088*cda5da8dSAndroid Build Coastguard Worker 1 2089*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pensize(10) # from here on lines of width 10 are drawn 2090*cda5da8dSAndroid Build Coastguard Worker """ 2091*cda5da8dSAndroid Build Coastguard Worker if width is None: 2092*cda5da8dSAndroid Build Coastguard Worker return self._pensize 2093*cda5da8dSAndroid Build Coastguard Worker self.pen(pensize=width) 2094*cda5da8dSAndroid Build Coastguard Worker 2095*cda5da8dSAndroid Build Coastguard Worker 2096*cda5da8dSAndroid Build Coastguard Worker def penup(self): 2097*cda5da8dSAndroid Build Coastguard Worker """Pull the pen up -- no drawing when moving. 2098*cda5da8dSAndroid Build Coastguard Worker 2099*cda5da8dSAndroid Build Coastguard Worker Aliases: penup | pu | up 2100*cda5da8dSAndroid Build Coastguard Worker 2101*cda5da8dSAndroid Build Coastguard Worker No argument 2102*cda5da8dSAndroid Build Coastguard Worker 2103*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2104*cda5da8dSAndroid Build Coastguard Worker >>> turtle.penup() 2105*cda5da8dSAndroid Build Coastguard Worker """ 2106*cda5da8dSAndroid Build Coastguard Worker if not self._drawing: 2107*cda5da8dSAndroid Build Coastguard Worker return 2108*cda5da8dSAndroid Build Coastguard Worker self.pen(pendown=False) 2109*cda5da8dSAndroid Build Coastguard Worker 2110*cda5da8dSAndroid Build Coastguard Worker def pendown(self): 2111*cda5da8dSAndroid Build Coastguard Worker """Pull the pen down -- drawing when moving. 2112*cda5da8dSAndroid Build Coastguard Worker 2113*cda5da8dSAndroid Build Coastguard Worker Aliases: pendown | pd | down 2114*cda5da8dSAndroid Build Coastguard Worker 2115*cda5da8dSAndroid Build Coastguard Worker No argument. 2116*cda5da8dSAndroid Build Coastguard Worker 2117*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2118*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pendown() 2119*cda5da8dSAndroid Build Coastguard Worker """ 2120*cda5da8dSAndroid Build Coastguard Worker if self._drawing: 2121*cda5da8dSAndroid Build Coastguard Worker return 2122*cda5da8dSAndroid Build Coastguard Worker self.pen(pendown=True) 2123*cda5da8dSAndroid Build Coastguard Worker 2124*cda5da8dSAndroid Build Coastguard Worker def isdown(self): 2125*cda5da8dSAndroid Build Coastguard Worker """Return True if pen is down, False if it's up. 2126*cda5da8dSAndroid Build Coastguard Worker 2127*cda5da8dSAndroid Build Coastguard Worker No argument. 2128*cda5da8dSAndroid Build Coastguard Worker 2129*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2130*cda5da8dSAndroid Build Coastguard Worker >>> turtle.penup() 2131*cda5da8dSAndroid Build Coastguard Worker >>> turtle.isdown() 2132*cda5da8dSAndroid Build Coastguard Worker False 2133*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pendown() 2134*cda5da8dSAndroid Build Coastguard Worker >>> turtle.isdown() 2135*cda5da8dSAndroid Build Coastguard Worker True 2136*cda5da8dSAndroid Build Coastguard Worker """ 2137*cda5da8dSAndroid Build Coastguard Worker return self._drawing 2138*cda5da8dSAndroid Build Coastguard Worker 2139*cda5da8dSAndroid Build Coastguard Worker def speed(self, speed=None): 2140*cda5da8dSAndroid Build Coastguard Worker """ Return or set the turtle's speed. 2141*cda5da8dSAndroid Build Coastguard Worker 2142*cda5da8dSAndroid Build Coastguard Worker Optional argument: 2143*cda5da8dSAndroid Build Coastguard Worker speed -- an integer in the range 0..10 or a speedstring (see below) 2144*cda5da8dSAndroid Build Coastguard Worker 2145*cda5da8dSAndroid Build Coastguard Worker Set the turtle's speed to an integer value in the range 0 .. 10. 2146*cda5da8dSAndroid Build Coastguard Worker If no argument is given: return current speed. 2147*cda5da8dSAndroid Build Coastguard Worker 2148*cda5da8dSAndroid Build Coastguard Worker If input is a number greater than 10 or smaller than 0.5, 2149*cda5da8dSAndroid Build Coastguard Worker speed is set to 0. 2150*cda5da8dSAndroid Build Coastguard Worker Speedstrings are mapped to speedvalues in the following way: 2151*cda5da8dSAndroid Build Coastguard Worker 'fastest' : 0 2152*cda5da8dSAndroid Build Coastguard Worker 'fast' : 10 2153*cda5da8dSAndroid Build Coastguard Worker 'normal' : 6 2154*cda5da8dSAndroid Build Coastguard Worker 'slow' : 3 2155*cda5da8dSAndroid Build Coastguard Worker 'slowest' : 1 2156*cda5da8dSAndroid Build Coastguard Worker speeds from 1 to 10 enforce increasingly faster animation of 2157*cda5da8dSAndroid Build Coastguard Worker line drawing and turtle turning. 2158*cda5da8dSAndroid Build Coastguard Worker 2159*cda5da8dSAndroid Build Coastguard Worker Attention: 2160*cda5da8dSAndroid Build Coastguard Worker speed = 0 : *no* animation takes place. forward/back makes turtle jump 2161*cda5da8dSAndroid Build Coastguard Worker and likewise left/right make the turtle turn instantly. 2162*cda5da8dSAndroid Build Coastguard Worker 2163*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2164*cda5da8dSAndroid Build Coastguard Worker >>> turtle.speed(3) 2165*cda5da8dSAndroid Build Coastguard Worker """ 2166*cda5da8dSAndroid Build Coastguard Worker speeds = {'fastest':0, 'fast':10, 'normal':6, 'slow':3, 'slowest':1 } 2167*cda5da8dSAndroid Build Coastguard Worker if speed is None: 2168*cda5da8dSAndroid Build Coastguard Worker return self._speed 2169*cda5da8dSAndroid Build Coastguard Worker if speed in speeds: 2170*cda5da8dSAndroid Build Coastguard Worker speed = speeds[speed] 2171*cda5da8dSAndroid Build Coastguard Worker elif 0.5 < speed < 10.5: 2172*cda5da8dSAndroid Build Coastguard Worker speed = int(round(speed)) 2173*cda5da8dSAndroid Build Coastguard Worker else: 2174*cda5da8dSAndroid Build Coastguard Worker speed = 0 2175*cda5da8dSAndroid Build Coastguard Worker self.pen(speed=speed) 2176*cda5da8dSAndroid Build Coastguard Worker 2177*cda5da8dSAndroid Build Coastguard Worker def color(self, *args): 2178*cda5da8dSAndroid Build Coastguard Worker """Return or set the pencolor and fillcolor. 2179*cda5da8dSAndroid Build Coastguard Worker 2180*cda5da8dSAndroid Build Coastguard Worker Arguments: 2181*cda5da8dSAndroid Build Coastguard Worker Several input formats are allowed. 2182*cda5da8dSAndroid Build Coastguard Worker They use 0, 1, 2, or 3 arguments as follows: 2183*cda5da8dSAndroid Build Coastguard Worker 2184*cda5da8dSAndroid Build Coastguard Worker color() 2185*cda5da8dSAndroid Build Coastguard Worker Return the current pencolor and the current fillcolor 2186*cda5da8dSAndroid Build Coastguard Worker as a pair of color specification strings as are returned 2187*cda5da8dSAndroid Build Coastguard Worker by pencolor and fillcolor. 2188*cda5da8dSAndroid Build Coastguard Worker color(colorstring), color((r,g,b)), color(r,g,b) 2189*cda5da8dSAndroid Build Coastguard Worker inputs as in pencolor, set both, fillcolor and pencolor, 2190*cda5da8dSAndroid Build Coastguard Worker to the given value. 2191*cda5da8dSAndroid Build Coastguard Worker color(colorstring1, colorstring2), 2192*cda5da8dSAndroid Build Coastguard Worker color((r1,g1,b1), (r2,g2,b2)) 2193*cda5da8dSAndroid Build Coastguard Worker equivalent to pencolor(colorstring1) and fillcolor(colorstring2) 2194*cda5da8dSAndroid Build Coastguard Worker and analogously, if the other input format is used. 2195*cda5da8dSAndroid Build Coastguard Worker 2196*cda5da8dSAndroid Build Coastguard Worker If turtleshape is a polygon, outline and interior of that polygon 2197*cda5da8dSAndroid Build Coastguard Worker is drawn with the newly set colors. 2198*cda5da8dSAndroid Build Coastguard Worker For more info see: pencolor, fillcolor 2199*cda5da8dSAndroid Build Coastguard Worker 2200*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2201*cda5da8dSAndroid Build Coastguard Worker >>> turtle.color('red', 'green') 2202*cda5da8dSAndroid Build Coastguard Worker >>> turtle.color() 2203*cda5da8dSAndroid Build Coastguard Worker ('red', 'green') 2204*cda5da8dSAndroid Build Coastguard Worker >>> colormode(255) 2205*cda5da8dSAndroid Build Coastguard Worker >>> color((40, 80, 120), (160, 200, 240)) 2206*cda5da8dSAndroid Build Coastguard Worker >>> color() 2207*cda5da8dSAndroid Build Coastguard Worker ('#285078', '#a0c8f0') 2208*cda5da8dSAndroid Build Coastguard Worker """ 2209*cda5da8dSAndroid Build Coastguard Worker if args: 2210*cda5da8dSAndroid Build Coastguard Worker l = len(args) 2211*cda5da8dSAndroid Build Coastguard Worker if l == 1: 2212*cda5da8dSAndroid Build Coastguard Worker pcolor = fcolor = args[0] 2213*cda5da8dSAndroid Build Coastguard Worker elif l == 2: 2214*cda5da8dSAndroid Build Coastguard Worker pcolor, fcolor = args 2215*cda5da8dSAndroid Build Coastguard Worker elif l == 3: 2216*cda5da8dSAndroid Build Coastguard Worker pcolor = fcolor = args 2217*cda5da8dSAndroid Build Coastguard Worker pcolor = self._colorstr(pcolor) 2218*cda5da8dSAndroid Build Coastguard Worker fcolor = self._colorstr(fcolor) 2219*cda5da8dSAndroid Build Coastguard Worker self.pen(pencolor=pcolor, fillcolor=fcolor) 2220*cda5da8dSAndroid Build Coastguard Worker else: 2221*cda5da8dSAndroid Build Coastguard Worker return self._color(self._pencolor), self._color(self._fillcolor) 2222*cda5da8dSAndroid Build Coastguard Worker 2223*cda5da8dSAndroid Build Coastguard Worker def pencolor(self, *args): 2224*cda5da8dSAndroid Build Coastguard Worker """ Return or set the pencolor. 2225*cda5da8dSAndroid Build Coastguard Worker 2226*cda5da8dSAndroid Build Coastguard Worker Arguments: 2227*cda5da8dSAndroid Build Coastguard Worker Four input formats are allowed: 2228*cda5da8dSAndroid Build Coastguard Worker - pencolor() 2229*cda5da8dSAndroid Build Coastguard Worker Return the current pencolor as color specification string, 2230*cda5da8dSAndroid Build Coastguard Worker possibly in hex-number format (see example). 2231*cda5da8dSAndroid Build Coastguard Worker May be used as input to another color/pencolor/fillcolor call. 2232*cda5da8dSAndroid Build Coastguard Worker - pencolor(colorstring) 2233*cda5da8dSAndroid Build Coastguard Worker s is a Tk color specification string, such as "red" or "yellow" 2234*cda5da8dSAndroid Build Coastguard Worker - pencolor((r, g, b)) 2235*cda5da8dSAndroid Build Coastguard Worker *a tuple* of r, g, and b, which represent, an RGB color, 2236*cda5da8dSAndroid Build Coastguard Worker and each of r, g, and b are in the range 0..colormode, 2237*cda5da8dSAndroid Build Coastguard Worker where colormode is either 1.0 or 255 2238*cda5da8dSAndroid Build Coastguard Worker - pencolor(r, g, b) 2239*cda5da8dSAndroid Build Coastguard Worker r, g, and b represent an RGB color, and each of r, g, and b 2240*cda5da8dSAndroid Build Coastguard Worker are in the range 0..colormode 2241*cda5da8dSAndroid Build Coastguard Worker 2242*cda5da8dSAndroid Build Coastguard Worker If turtleshape is a polygon, the outline of that polygon is drawn 2243*cda5da8dSAndroid Build Coastguard Worker with the newly set pencolor. 2244*cda5da8dSAndroid Build Coastguard Worker 2245*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2246*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pencolor('brown') 2247*cda5da8dSAndroid Build Coastguard Worker >>> tup = (0.2, 0.8, 0.55) 2248*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pencolor(tup) 2249*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pencolor() 2250*cda5da8dSAndroid Build Coastguard Worker '#33cc8c' 2251*cda5da8dSAndroid Build Coastguard Worker """ 2252*cda5da8dSAndroid Build Coastguard Worker if args: 2253*cda5da8dSAndroid Build Coastguard Worker color = self._colorstr(args) 2254*cda5da8dSAndroid Build Coastguard Worker if color == self._pencolor: 2255*cda5da8dSAndroid Build Coastguard Worker return 2256*cda5da8dSAndroid Build Coastguard Worker self.pen(pencolor=color) 2257*cda5da8dSAndroid Build Coastguard Worker else: 2258*cda5da8dSAndroid Build Coastguard Worker return self._color(self._pencolor) 2259*cda5da8dSAndroid Build Coastguard Worker 2260*cda5da8dSAndroid Build Coastguard Worker def fillcolor(self, *args): 2261*cda5da8dSAndroid Build Coastguard Worker """ Return or set the fillcolor. 2262*cda5da8dSAndroid Build Coastguard Worker 2263*cda5da8dSAndroid Build Coastguard Worker Arguments: 2264*cda5da8dSAndroid Build Coastguard Worker Four input formats are allowed: 2265*cda5da8dSAndroid Build Coastguard Worker - fillcolor() 2266*cda5da8dSAndroid Build Coastguard Worker Return the current fillcolor as color specification string, 2267*cda5da8dSAndroid Build Coastguard Worker possibly in hex-number format (see example). 2268*cda5da8dSAndroid Build Coastguard Worker May be used as input to another color/pencolor/fillcolor call. 2269*cda5da8dSAndroid Build Coastguard Worker - fillcolor(colorstring) 2270*cda5da8dSAndroid Build Coastguard Worker s is a Tk color specification string, such as "red" or "yellow" 2271*cda5da8dSAndroid Build Coastguard Worker - fillcolor((r, g, b)) 2272*cda5da8dSAndroid Build Coastguard Worker *a tuple* of r, g, and b, which represent, an RGB color, 2273*cda5da8dSAndroid Build Coastguard Worker and each of r, g, and b are in the range 0..colormode, 2274*cda5da8dSAndroid Build Coastguard Worker where colormode is either 1.0 or 255 2275*cda5da8dSAndroid Build Coastguard Worker - fillcolor(r, g, b) 2276*cda5da8dSAndroid Build Coastguard Worker r, g, and b represent an RGB color, and each of r, g, and b 2277*cda5da8dSAndroid Build Coastguard Worker are in the range 0..colormode 2278*cda5da8dSAndroid Build Coastguard Worker 2279*cda5da8dSAndroid Build Coastguard Worker If turtleshape is a polygon, the interior of that polygon is drawn 2280*cda5da8dSAndroid Build Coastguard Worker with the newly set fillcolor. 2281*cda5da8dSAndroid Build Coastguard Worker 2282*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2283*cda5da8dSAndroid Build Coastguard Worker >>> turtle.fillcolor('violet') 2284*cda5da8dSAndroid Build Coastguard Worker >>> col = turtle.pencolor() 2285*cda5da8dSAndroid Build Coastguard Worker >>> turtle.fillcolor(col) 2286*cda5da8dSAndroid Build Coastguard Worker >>> turtle.fillcolor(0, .5, 0) 2287*cda5da8dSAndroid Build Coastguard Worker """ 2288*cda5da8dSAndroid Build Coastguard Worker if args: 2289*cda5da8dSAndroid Build Coastguard Worker color = self._colorstr(args) 2290*cda5da8dSAndroid Build Coastguard Worker if color == self._fillcolor: 2291*cda5da8dSAndroid Build Coastguard Worker return 2292*cda5da8dSAndroid Build Coastguard Worker self.pen(fillcolor=color) 2293*cda5da8dSAndroid Build Coastguard Worker else: 2294*cda5da8dSAndroid Build Coastguard Worker return self._color(self._fillcolor) 2295*cda5da8dSAndroid Build Coastguard Worker 2296*cda5da8dSAndroid Build Coastguard Worker def showturtle(self): 2297*cda5da8dSAndroid Build Coastguard Worker """Makes the turtle visible. 2298*cda5da8dSAndroid Build Coastguard Worker 2299*cda5da8dSAndroid Build Coastguard Worker Aliases: showturtle | st 2300*cda5da8dSAndroid Build Coastguard Worker 2301*cda5da8dSAndroid Build Coastguard Worker No argument. 2302*cda5da8dSAndroid Build Coastguard Worker 2303*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2304*cda5da8dSAndroid Build Coastguard Worker >>> turtle.hideturtle() 2305*cda5da8dSAndroid Build Coastguard Worker >>> turtle.showturtle() 2306*cda5da8dSAndroid Build Coastguard Worker """ 2307*cda5da8dSAndroid Build Coastguard Worker self.pen(shown=True) 2308*cda5da8dSAndroid Build Coastguard Worker 2309*cda5da8dSAndroid Build Coastguard Worker def hideturtle(self): 2310*cda5da8dSAndroid Build Coastguard Worker """Makes the turtle invisible. 2311*cda5da8dSAndroid Build Coastguard Worker 2312*cda5da8dSAndroid Build Coastguard Worker Aliases: hideturtle | ht 2313*cda5da8dSAndroid Build Coastguard Worker 2314*cda5da8dSAndroid Build Coastguard Worker No argument. 2315*cda5da8dSAndroid Build Coastguard Worker 2316*cda5da8dSAndroid Build Coastguard Worker It's a good idea to do this while you're in the 2317*cda5da8dSAndroid Build Coastguard Worker middle of a complicated drawing, because hiding 2318*cda5da8dSAndroid Build Coastguard Worker the turtle speeds up the drawing observably. 2319*cda5da8dSAndroid Build Coastguard Worker 2320*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2321*cda5da8dSAndroid Build Coastguard Worker >>> turtle.hideturtle() 2322*cda5da8dSAndroid Build Coastguard Worker """ 2323*cda5da8dSAndroid Build Coastguard Worker self.pen(shown=False) 2324*cda5da8dSAndroid Build Coastguard Worker 2325*cda5da8dSAndroid Build Coastguard Worker def isvisible(self): 2326*cda5da8dSAndroid Build Coastguard Worker """Return True if the Turtle is shown, False if it's hidden. 2327*cda5da8dSAndroid Build Coastguard Worker 2328*cda5da8dSAndroid Build Coastguard Worker No argument. 2329*cda5da8dSAndroid Build Coastguard Worker 2330*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2331*cda5da8dSAndroid Build Coastguard Worker >>> turtle.hideturtle() 2332*cda5da8dSAndroid Build Coastguard Worker >>> print turtle.isvisible(): 2333*cda5da8dSAndroid Build Coastguard Worker False 2334*cda5da8dSAndroid Build Coastguard Worker """ 2335*cda5da8dSAndroid Build Coastguard Worker return self._shown 2336*cda5da8dSAndroid Build Coastguard Worker 2337*cda5da8dSAndroid Build Coastguard Worker def pen(self, pen=None, **pendict): 2338*cda5da8dSAndroid Build Coastguard Worker """Return or set the pen's attributes. 2339*cda5da8dSAndroid Build Coastguard Worker 2340*cda5da8dSAndroid Build Coastguard Worker Arguments: 2341*cda5da8dSAndroid Build Coastguard Worker pen -- a dictionary with some or all of the below listed keys. 2342*cda5da8dSAndroid Build Coastguard Worker **pendict -- one or more keyword-arguments with the below 2343*cda5da8dSAndroid Build Coastguard Worker listed keys as keywords. 2344*cda5da8dSAndroid Build Coastguard Worker 2345*cda5da8dSAndroid Build Coastguard Worker Return or set the pen's attributes in a 'pen-dictionary' 2346*cda5da8dSAndroid Build Coastguard Worker with the following key/value pairs: 2347*cda5da8dSAndroid Build Coastguard Worker "shown" : True/False 2348*cda5da8dSAndroid Build Coastguard Worker "pendown" : True/False 2349*cda5da8dSAndroid Build Coastguard Worker "pencolor" : color-string or color-tuple 2350*cda5da8dSAndroid Build Coastguard Worker "fillcolor" : color-string or color-tuple 2351*cda5da8dSAndroid Build Coastguard Worker "pensize" : positive number 2352*cda5da8dSAndroid Build Coastguard Worker "speed" : number in range 0..10 2353*cda5da8dSAndroid Build Coastguard Worker "resizemode" : "auto" or "user" or "noresize" 2354*cda5da8dSAndroid Build Coastguard Worker "stretchfactor": (positive number, positive number) 2355*cda5da8dSAndroid Build Coastguard Worker "shearfactor": number 2356*cda5da8dSAndroid Build Coastguard Worker "outline" : positive number 2357*cda5da8dSAndroid Build Coastguard Worker "tilt" : number 2358*cda5da8dSAndroid Build Coastguard Worker 2359*cda5da8dSAndroid Build Coastguard Worker This dictionary can be used as argument for a subsequent 2360*cda5da8dSAndroid Build Coastguard Worker pen()-call to restore the former pen-state. Moreover one 2361*cda5da8dSAndroid Build Coastguard Worker or more of these attributes can be provided as keyword-arguments. 2362*cda5da8dSAndroid Build Coastguard Worker This can be used to set several pen attributes in one statement. 2363*cda5da8dSAndroid Build Coastguard Worker 2364*cda5da8dSAndroid Build Coastguard Worker 2365*cda5da8dSAndroid Build Coastguard Worker Examples (for a Turtle instance named turtle): 2366*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10) 2367*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pen() 2368*cda5da8dSAndroid Build Coastguard Worker {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1, 2369*cda5da8dSAndroid Build Coastguard Worker 'pencolor': 'red', 'pendown': True, 'fillcolor': 'black', 2370*cda5da8dSAndroid Build Coastguard Worker 'stretchfactor': (1,1), 'speed': 3, 'shearfactor': 0.0} 2371*cda5da8dSAndroid Build Coastguard Worker >>> penstate=turtle.pen() 2372*cda5da8dSAndroid Build Coastguard Worker >>> turtle.color("yellow","") 2373*cda5da8dSAndroid Build Coastguard Worker >>> turtle.penup() 2374*cda5da8dSAndroid Build Coastguard Worker >>> turtle.pen() 2375*cda5da8dSAndroid Build Coastguard Worker {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1, 2376*cda5da8dSAndroid Build Coastguard Worker 'pencolor': 'yellow', 'pendown': False, 'fillcolor': '', 2377*cda5da8dSAndroid Build Coastguard Worker 'stretchfactor': (1,1), 'speed': 3, 'shearfactor': 0.0} 2378*cda5da8dSAndroid Build Coastguard Worker >>> p.pen(penstate, fillcolor="green") 2379*cda5da8dSAndroid Build Coastguard Worker >>> p.pen() 2380*cda5da8dSAndroid Build Coastguard Worker {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1, 2381*cda5da8dSAndroid Build Coastguard Worker 'pencolor': 'red', 'pendown': True, 'fillcolor': 'green', 2382*cda5da8dSAndroid Build Coastguard Worker 'stretchfactor': (1,1), 'speed': 3, 'shearfactor': 0.0} 2383*cda5da8dSAndroid Build Coastguard Worker """ 2384*cda5da8dSAndroid Build Coastguard Worker _pd = {"shown" : self._shown, 2385*cda5da8dSAndroid Build Coastguard Worker "pendown" : self._drawing, 2386*cda5da8dSAndroid Build Coastguard Worker "pencolor" : self._pencolor, 2387*cda5da8dSAndroid Build Coastguard Worker "fillcolor" : self._fillcolor, 2388*cda5da8dSAndroid Build Coastguard Worker "pensize" : self._pensize, 2389*cda5da8dSAndroid Build Coastguard Worker "speed" : self._speed, 2390*cda5da8dSAndroid Build Coastguard Worker "resizemode" : self._resizemode, 2391*cda5da8dSAndroid Build Coastguard Worker "stretchfactor" : self._stretchfactor, 2392*cda5da8dSAndroid Build Coastguard Worker "shearfactor" : self._shearfactor, 2393*cda5da8dSAndroid Build Coastguard Worker "outline" : self._outlinewidth, 2394*cda5da8dSAndroid Build Coastguard Worker "tilt" : self._tilt 2395*cda5da8dSAndroid Build Coastguard Worker } 2396*cda5da8dSAndroid Build Coastguard Worker 2397*cda5da8dSAndroid Build Coastguard Worker if not (pen or pendict): 2398*cda5da8dSAndroid Build Coastguard Worker return _pd 2399*cda5da8dSAndroid Build Coastguard Worker 2400*cda5da8dSAndroid Build Coastguard Worker if isinstance(pen, dict): 2401*cda5da8dSAndroid Build Coastguard Worker p = pen 2402*cda5da8dSAndroid Build Coastguard Worker else: 2403*cda5da8dSAndroid Build Coastguard Worker p = {} 2404*cda5da8dSAndroid Build Coastguard Worker p.update(pendict) 2405*cda5da8dSAndroid Build Coastguard Worker 2406*cda5da8dSAndroid Build Coastguard Worker _p_buf = {} 2407*cda5da8dSAndroid Build Coastguard Worker for key in p: 2408*cda5da8dSAndroid Build Coastguard Worker _p_buf[key] = _pd[key] 2409*cda5da8dSAndroid Build Coastguard Worker 2410*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer: 2411*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.push(("pen", _p_buf)) 2412*cda5da8dSAndroid Build Coastguard Worker 2413*cda5da8dSAndroid Build Coastguard Worker newLine = False 2414*cda5da8dSAndroid Build Coastguard Worker if "pendown" in p: 2415*cda5da8dSAndroid Build Coastguard Worker if self._drawing != p["pendown"]: 2416*cda5da8dSAndroid Build Coastguard Worker newLine = True 2417*cda5da8dSAndroid Build Coastguard Worker if "pencolor" in p: 2418*cda5da8dSAndroid Build Coastguard Worker if isinstance(p["pencolor"], tuple): 2419*cda5da8dSAndroid Build Coastguard Worker p["pencolor"] = self._colorstr((p["pencolor"],)) 2420*cda5da8dSAndroid Build Coastguard Worker if self._pencolor != p["pencolor"]: 2421*cda5da8dSAndroid Build Coastguard Worker newLine = True 2422*cda5da8dSAndroid Build Coastguard Worker if "pensize" in p: 2423*cda5da8dSAndroid Build Coastguard Worker if self._pensize != p["pensize"]: 2424*cda5da8dSAndroid Build Coastguard Worker newLine = True 2425*cda5da8dSAndroid Build Coastguard Worker if newLine: 2426*cda5da8dSAndroid Build Coastguard Worker self._newLine() 2427*cda5da8dSAndroid Build Coastguard Worker if "pendown" in p: 2428*cda5da8dSAndroid Build Coastguard Worker self._drawing = p["pendown"] 2429*cda5da8dSAndroid Build Coastguard Worker if "pencolor" in p: 2430*cda5da8dSAndroid Build Coastguard Worker self._pencolor = p["pencolor"] 2431*cda5da8dSAndroid Build Coastguard Worker if "pensize" in p: 2432*cda5da8dSAndroid Build Coastguard Worker self._pensize = p["pensize"] 2433*cda5da8dSAndroid Build Coastguard Worker if "fillcolor" in p: 2434*cda5da8dSAndroid Build Coastguard Worker if isinstance(p["fillcolor"], tuple): 2435*cda5da8dSAndroid Build Coastguard Worker p["fillcolor"] = self._colorstr((p["fillcolor"],)) 2436*cda5da8dSAndroid Build Coastguard Worker self._fillcolor = p["fillcolor"] 2437*cda5da8dSAndroid Build Coastguard Worker if "speed" in p: 2438*cda5da8dSAndroid Build Coastguard Worker self._speed = p["speed"] 2439*cda5da8dSAndroid Build Coastguard Worker if "resizemode" in p: 2440*cda5da8dSAndroid Build Coastguard Worker self._resizemode = p["resizemode"] 2441*cda5da8dSAndroid Build Coastguard Worker if "stretchfactor" in p: 2442*cda5da8dSAndroid Build Coastguard Worker sf = p["stretchfactor"] 2443*cda5da8dSAndroid Build Coastguard Worker if isinstance(sf, (int, float)): 2444*cda5da8dSAndroid Build Coastguard Worker sf = (sf, sf) 2445*cda5da8dSAndroid Build Coastguard Worker self._stretchfactor = sf 2446*cda5da8dSAndroid Build Coastguard Worker if "shearfactor" in p: 2447*cda5da8dSAndroid Build Coastguard Worker self._shearfactor = p["shearfactor"] 2448*cda5da8dSAndroid Build Coastguard Worker if "outline" in p: 2449*cda5da8dSAndroid Build Coastguard Worker self._outlinewidth = p["outline"] 2450*cda5da8dSAndroid Build Coastguard Worker if "shown" in p: 2451*cda5da8dSAndroid Build Coastguard Worker self._shown = p["shown"] 2452*cda5da8dSAndroid Build Coastguard Worker if "tilt" in p: 2453*cda5da8dSAndroid Build Coastguard Worker self._tilt = p["tilt"] 2454*cda5da8dSAndroid Build Coastguard Worker if "stretchfactor" in p or "tilt" in p or "shearfactor" in p: 2455*cda5da8dSAndroid Build Coastguard Worker scx, scy = self._stretchfactor 2456*cda5da8dSAndroid Build Coastguard Worker shf = self._shearfactor 2457*cda5da8dSAndroid Build Coastguard Worker sa, ca = math.sin(self._tilt), math.cos(self._tilt) 2458*cda5da8dSAndroid Build Coastguard Worker self._shapetrafo = ( scx*ca, scy*(shf*ca + sa), 2459*cda5da8dSAndroid Build Coastguard Worker -scx*sa, scy*(ca - shf*sa)) 2460*cda5da8dSAndroid Build Coastguard Worker self._update() 2461*cda5da8dSAndroid Build Coastguard Worker 2462*cda5da8dSAndroid Build Coastguard Worker## three dummy methods to be implemented by child class: 2463*cda5da8dSAndroid Build Coastguard Worker 2464*cda5da8dSAndroid Build Coastguard Worker def _newLine(self, usePos = True): 2465*cda5da8dSAndroid Build Coastguard Worker """dummy method - to be overwritten by child class""" 2466*cda5da8dSAndroid Build Coastguard Worker def _update(self, count=True, forced=False): 2467*cda5da8dSAndroid Build Coastguard Worker """dummy method - to be overwritten by child class""" 2468*cda5da8dSAndroid Build Coastguard Worker def _color(self, args): 2469*cda5da8dSAndroid Build Coastguard Worker """dummy method - to be overwritten by child class""" 2470*cda5da8dSAndroid Build Coastguard Worker def _colorstr(self, args): 2471*cda5da8dSAndroid Build Coastguard Worker """dummy method - to be overwritten by child class""" 2472*cda5da8dSAndroid Build Coastguard Worker 2473*cda5da8dSAndroid Build Coastguard Worker width = pensize 2474*cda5da8dSAndroid Build Coastguard Worker up = penup 2475*cda5da8dSAndroid Build Coastguard Worker pu = penup 2476*cda5da8dSAndroid Build Coastguard Worker pd = pendown 2477*cda5da8dSAndroid Build Coastguard Worker down = pendown 2478*cda5da8dSAndroid Build Coastguard Worker st = showturtle 2479*cda5da8dSAndroid Build Coastguard Worker ht = hideturtle 2480*cda5da8dSAndroid Build Coastguard Worker 2481*cda5da8dSAndroid Build Coastguard Worker 2482*cda5da8dSAndroid Build Coastguard Workerclass _TurtleImage(object): 2483*cda5da8dSAndroid Build Coastguard Worker """Helper class: Datatype to store Turtle attributes 2484*cda5da8dSAndroid Build Coastguard Worker """ 2485*cda5da8dSAndroid Build Coastguard Worker 2486*cda5da8dSAndroid Build Coastguard Worker def __init__(self, screen, shapeIndex): 2487*cda5da8dSAndroid Build Coastguard Worker self.screen = screen 2488*cda5da8dSAndroid Build Coastguard Worker self._type = None 2489*cda5da8dSAndroid Build Coastguard Worker self._setshape(shapeIndex) 2490*cda5da8dSAndroid Build Coastguard Worker 2491*cda5da8dSAndroid Build Coastguard Worker def _setshape(self, shapeIndex): 2492*cda5da8dSAndroid Build Coastguard Worker screen = self.screen 2493*cda5da8dSAndroid Build Coastguard Worker self.shapeIndex = shapeIndex 2494*cda5da8dSAndroid Build Coastguard Worker if self._type == "polygon" == screen._shapes[shapeIndex]._type: 2495*cda5da8dSAndroid Build Coastguard Worker return 2496*cda5da8dSAndroid Build Coastguard Worker if self._type == "image" == screen._shapes[shapeIndex]._type: 2497*cda5da8dSAndroid Build Coastguard Worker return 2498*cda5da8dSAndroid Build Coastguard Worker if self._type in ["image", "polygon"]: 2499*cda5da8dSAndroid Build Coastguard Worker screen._delete(self._item) 2500*cda5da8dSAndroid Build Coastguard Worker elif self._type == "compound": 2501*cda5da8dSAndroid Build Coastguard Worker for item in self._item: 2502*cda5da8dSAndroid Build Coastguard Worker screen._delete(item) 2503*cda5da8dSAndroid Build Coastguard Worker self._type = screen._shapes[shapeIndex]._type 2504*cda5da8dSAndroid Build Coastguard Worker if self._type == "polygon": 2505*cda5da8dSAndroid Build Coastguard Worker self._item = screen._createpoly() 2506*cda5da8dSAndroid Build Coastguard Worker elif self._type == "image": 2507*cda5da8dSAndroid Build Coastguard Worker self._item = screen._createimage(screen._shapes["blank"]._data) 2508*cda5da8dSAndroid Build Coastguard Worker elif self._type == "compound": 2509*cda5da8dSAndroid Build Coastguard Worker self._item = [screen._createpoly() for item in 2510*cda5da8dSAndroid Build Coastguard Worker screen._shapes[shapeIndex]._data] 2511*cda5da8dSAndroid Build Coastguard Worker 2512*cda5da8dSAndroid Build Coastguard Worker 2513*cda5da8dSAndroid Build Coastguard Workerclass RawTurtle(TPen, TNavigator): 2514*cda5da8dSAndroid Build Coastguard Worker """Animation part of the RawTurtle. 2515*cda5da8dSAndroid Build Coastguard Worker Puts RawTurtle upon a TurtleScreen and provides tools for 2516*cda5da8dSAndroid Build Coastguard Worker its animation. 2517*cda5da8dSAndroid Build Coastguard Worker """ 2518*cda5da8dSAndroid Build Coastguard Worker screens = [] 2519*cda5da8dSAndroid Build Coastguard Worker 2520*cda5da8dSAndroid Build Coastguard Worker def __init__(self, canvas=None, 2521*cda5da8dSAndroid Build Coastguard Worker shape=_CFG["shape"], 2522*cda5da8dSAndroid Build Coastguard Worker undobuffersize=_CFG["undobuffersize"], 2523*cda5da8dSAndroid Build Coastguard Worker visible=_CFG["visible"]): 2524*cda5da8dSAndroid Build Coastguard Worker if isinstance(canvas, _Screen): 2525*cda5da8dSAndroid Build Coastguard Worker self.screen = canvas 2526*cda5da8dSAndroid Build Coastguard Worker elif isinstance(canvas, TurtleScreen): 2527*cda5da8dSAndroid Build Coastguard Worker if canvas not in RawTurtle.screens: 2528*cda5da8dSAndroid Build Coastguard Worker RawTurtle.screens.append(canvas) 2529*cda5da8dSAndroid Build Coastguard Worker self.screen = canvas 2530*cda5da8dSAndroid Build Coastguard Worker elif isinstance(canvas, (ScrolledCanvas, Canvas)): 2531*cda5da8dSAndroid Build Coastguard Worker for screen in RawTurtle.screens: 2532*cda5da8dSAndroid Build Coastguard Worker if screen.cv == canvas: 2533*cda5da8dSAndroid Build Coastguard Worker self.screen = screen 2534*cda5da8dSAndroid Build Coastguard Worker break 2535*cda5da8dSAndroid Build Coastguard Worker else: 2536*cda5da8dSAndroid Build Coastguard Worker self.screen = TurtleScreen(canvas) 2537*cda5da8dSAndroid Build Coastguard Worker RawTurtle.screens.append(self.screen) 2538*cda5da8dSAndroid Build Coastguard Worker else: 2539*cda5da8dSAndroid Build Coastguard Worker raise TurtleGraphicsError("bad canvas argument %s" % canvas) 2540*cda5da8dSAndroid Build Coastguard Worker 2541*cda5da8dSAndroid Build Coastguard Worker screen = self.screen 2542*cda5da8dSAndroid Build Coastguard Worker TNavigator.__init__(self, screen.mode()) 2543*cda5da8dSAndroid Build Coastguard Worker TPen.__init__(self) 2544*cda5da8dSAndroid Build Coastguard Worker screen._turtles.append(self) 2545*cda5da8dSAndroid Build Coastguard Worker self.drawingLineItem = screen._createline() 2546*cda5da8dSAndroid Build Coastguard Worker self.turtle = _TurtleImage(screen, shape) 2547*cda5da8dSAndroid Build Coastguard Worker self._poly = None 2548*cda5da8dSAndroid Build Coastguard Worker self._creatingPoly = False 2549*cda5da8dSAndroid Build Coastguard Worker self._fillitem = self._fillpath = None 2550*cda5da8dSAndroid Build Coastguard Worker self._shown = visible 2551*cda5da8dSAndroid Build Coastguard Worker self._hidden_from_screen = False 2552*cda5da8dSAndroid Build Coastguard Worker self.currentLineItem = screen._createline() 2553*cda5da8dSAndroid Build Coastguard Worker self.currentLine = [self._position] 2554*cda5da8dSAndroid Build Coastguard Worker self.items = [self.currentLineItem] 2555*cda5da8dSAndroid Build Coastguard Worker self.stampItems = [] 2556*cda5da8dSAndroid Build Coastguard Worker self._undobuffersize = undobuffersize 2557*cda5da8dSAndroid Build Coastguard Worker self.undobuffer = Tbuffer(undobuffersize) 2558*cda5da8dSAndroid Build Coastguard Worker self._update() 2559*cda5da8dSAndroid Build Coastguard Worker 2560*cda5da8dSAndroid Build Coastguard Worker def reset(self): 2561*cda5da8dSAndroid Build Coastguard Worker """Delete the turtle's drawings and restore its default values. 2562*cda5da8dSAndroid Build Coastguard Worker 2563*cda5da8dSAndroid Build Coastguard Worker No argument. 2564*cda5da8dSAndroid Build Coastguard Worker 2565*cda5da8dSAndroid Build Coastguard Worker Delete the turtle's drawings from the screen, re-center the turtle 2566*cda5da8dSAndroid Build Coastguard Worker and set variables to the default values. 2567*cda5da8dSAndroid Build Coastguard Worker 2568*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2569*cda5da8dSAndroid Build Coastguard Worker >>> turtle.position() 2570*cda5da8dSAndroid Build Coastguard Worker (0.00,-22.00) 2571*cda5da8dSAndroid Build Coastguard Worker >>> turtle.heading() 2572*cda5da8dSAndroid Build Coastguard Worker 100.0 2573*cda5da8dSAndroid Build Coastguard Worker >>> turtle.reset() 2574*cda5da8dSAndroid Build Coastguard Worker >>> turtle.position() 2575*cda5da8dSAndroid Build Coastguard Worker (0.00,0.00) 2576*cda5da8dSAndroid Build Coastguard Worker >>> turtle.heading() 2577*cda5da8dSAndroid Build Coastguard Worker 0.0 2578*cda5da8dSAndroid Build Coastguard Worker """ 2579*cda5da8dSAndroid Build Coastguard Worker TNavigator.reset(self) 2580*cda5da8dSAndroid Build Coastguard Worker TPen._reset(self) 2581*cda5da8dSAndroid Build Coastguard Worker self._clear() 2582*cda5da8dSAndroid Build Coastguard Worker self._drawturtle() 2583*cda5da8dSAndroid Build Coastguard Worker self._update() 2584*cda5da8dSAndroid Build Coastguard Worker 2585*cda5da8dSAndroid Build Coastguard Worker def setundobuffer(self, size): 2586*cda5da8dSAndroid Build Coastguard Worker """Set or disable undobuffer. 2587*cda5da8dSAndroid Build Coastguard Worker 2588*cda5da8dSAndroid Build Coastguard Worker Argument: 2589*cda5da8dSAndroid Build Coastguard Worker size -- an integer or None 2590*cda5da8dSAndroid Build Coastguard Worker 2591*cda5da8dSAndroid Build Coastguard Worker If size is an integer an empty undobuffer of given size is installed. 2592*cda5da8dSAndroid Build Coastguard Worker Size gives the maximum number of turtle-actions that can be undone 2593*cda5da8dSAndroid Build Coastguard Worker by the undo() function. 2594*cda5da8dSAndroid Build Coastguard Worker If size is None, no undobuffer is present. 2595*cda5da8dSAndroid Build Coastguard Worker 2596*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2597*cda5da8dSAndroid Build Coastguard Worker >>> turtle.setundobuffer(42) 2598*cda5da8dSAndroid Build Coastguard Worker """ 2599*cda5da8dSAndroid Build Coastguard Worker if size is None or size <= 0: 2600*cda5da8dSAndroid Build Coastguard Worker self.undobuffer = None 2601*cda5da8dSAndroid Build Coastguard Worker else: 2602*cda5da8dSAndroid Build Coastguard Worker self.undobuffer = Tbuffer(size) 2603*cda5da8dSAndroid Build Coastguard Worker 2604*cda5da8dSAndroid Build Coastguard Worker def undobufferentries(self): 2605*cda5da8dSAndroid Build Coastguard Worker """Return count of entries in the undobuffer. 2606*cda5da8dSAndroid Build Coastguard Worker 2607*cda5da8dSAndroid Build Coastguard Worker No argument. 2608*cda5da8dSAndroid Build Coastguard Worker 2609*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2610*cda5da8dSAndroid Build Coastguard Worker >>> while undobufferentries(): 2611*cda5da8dSAndroid Build Coastguard Worker ... undo() 2612*cda5da8dSAndroid Build Coastguard Worker """ 2613*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer is None: 2614*cda5da8dSAndroid Build Coastguard Worker return 0 2615*cda5da8dSAndroid Build Coastguard Worker return self.undobuffer.nr_of_items() 2616*cda5da8dSAndroid Build Coastguard Worker 2617*cda5da8dSAndroid Build Coastguard Worker def _clear(self): 2618*cda5da8dSAndroid Build Coastguard Worker """Delete all of pen's drawings""" 2619*cda5da8dSAndroid Build Coastguard Worker self._fillitem = self._fillpath = None 2620*cda5da8dSAndroid Build Coastguard Worker for item in self.items: 2621*cda5da8dSAndroid Build Coastguard Worker self.screen._delete(item) 2622*cda5da8dSAndroid Build Coastguard Worker self.currentLineItem = self.screen._createline() 2623*cda5da8dSAndroid Build Coastguard Worker self.currentLine = [] 2624*cda5da8dSAndroid Build Coastguard Worker if self._drawing: 2625*cda5da8dSAndroid Build Coastguard Worker self.currentLine.append(self._position) 2626*cda5da8dSAndroid Build Coastguard Worker self.items = [self.currentLineItem] 2627*cda5da8dSAndroid Build Coastguard Worker self.clearstamps() 2628*cda5da8dSAndroid Build Coastguard Worker self.setundobuffer(self._undobuffersize) 2629*cda5da8dSAndroid Build Coastguard Worker 2630*cda5da8dSAndroid Build Coastguard Worker 2631*cda5da8dSAndroid Build Coastguard Worker def clear(self): 2632*cda5da8dSAndroid Build Coastguard Worker """Delete the turtle's drawings from the screen. Do not move turtle. 2633*cda5da8dSAndroid Build Coastguard Worker 2634*cda5da8dSAndroid Build Coastguard Worker No arguments. 2635*cda5da8dSAndroid Build Coastguard Worker 2636*cda5da8dSAndroid Build Coastguard Worker Delete the turtle's drawings from the screen. Do not move turtle. 2637*cda5da8dSAndroid Build Coastguard Worker State and position of the turtle as well as drawings of other 2638*cda5da8dSAndroid Build Coastguard Worker turtles are not affected. 2639*cda5da8dSAndroid Build Coastguard Worker 2640*cda5da8dSAndroid Build Coastguard Worker Examples (for a Turtle instance named turtle): 2641*cda5da8dSAndroid Build Coastguard Worker >>> turtle.clear() 2642*cda5da8dSAndroid Build Coastguard Worker """ 2643*cda5da8dSAndroid Build Coastguard Worker self._clear() 2644*cda5da8dSAndroid Build Coastguard Worker self._update() 2645*cda5da8dSAndroid Build Coastguard Worker 2646*cda5da8dSAndroid Build Coastguard Worker def _update_data(self): 2647*cda5da8dSAndroid Build Coastguard Worker self.screen._incrementudc() 2648*cda5da8dSAndroid Build Coastguard Worker if self.screen._updatecounter != 0: 2649*cda5da8dSAndroid Build Coastguard Worker return 2650*cda5da8dSAndroid Build Coastguard Worker if len(self.currentLine)>1: 2651*cda5da8dSAndroid Build Coastguard Worker self.screen._drawline(self.currentLineItem, self.currentLine, 2652*cda5da8dSAndroid Build Coastguard Worker self._pencolor, self._pensize) 2653*cda5da8dSAndroid Build Coastguard Worker 2654*cda5da8dSAndroid Build Coastguard Worker def _update(self): 2655*cda5da8dSAndroid Build Coastguard Worker """Perform a Turtle-data update. 2656*cda5da8dSAndroid Build Coastguard Worker """ 2657*cda5da8dSAndroid Build Coastguard Worker screen = self.screen 2658*cda5da8dSAndroid Build Coastguard Worker if screen._tracing == 0: 2659*cda5da8dSAndroid Build Coastguard Worker return 2660*cda5da8dSAndroid Build Coastguard Worker elif screen._tracing == 1: 2661*cda5da8dSAndroid Build Coastguard Worker self._update_data() 2662*cda5da8dSAndroid Build Coastguard Worker self._drawturtle() 2663*cda5da8dSAndroid Build Coastguard Worker screen._update() # TurtleScreenBase 2664*cda5da8dSAndroid Build Coastguard Worker screen._delay(screen._delayvalue) # TurtleScreenBase 2665*cda5da8dSAndroid Build Coastguard Worker else: 2666*cda5da8dSAndroid Build Coastguard Worker self._update_data() 2667*cda5da8dSAndroid Build Coastguard Worker if screen._updatecounter == 0: 2668*cda5da8dSAndroid Build Coastguard Worker for t in screen.turtles(): 2669*cda5da8dSAndroid Build Coastguard Worker t._drawturtle() 2670*cda5da8dSAndroid Build Coastguard Worker screen._update() 2671*cda5da8dSAndroid Build Coastguard Worker 2672*cda5da8dSAndroid Build Coastguard Worker def _tracer(self, flag=None, delay=None): 2673*cda5da8dSAndroid Build Coastguard Worker """Turns turtle animation on/off and set delay for update drawings. 2674*cda5da8dSAndroid Build Coastguard Worker 2675*cda5da8dSAndroid Build Coastguard Worker Optional arguments: 2676*cda5da8dSAndroid Build Coastguard Worker n -- nonnegative integer 2677*cda5da8dSAndroid Build Coastguard Worker delay -- nonnegative integer 2678*cda5da8dSAndroid Build Coastguard Worker 2679*cda5da8dSAndroid Build Coastguard Worker If n is given, only each n-th regular screen update is really performed. 2680*cda5da8dSAndroid Build Coastguard Worker (Can be used to accelerate the drawing of complex graphics.) 2681*cda5da8dSAndroid Build Coastguard Worker Second arguments sets delay value (see RawTurtle.delay()) 2682*cda5da8dSAndroid Build Coastguard Worker 2683*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2684*cda5da8dSAndroid Build Coastguard Worker >>> turtle.tracer(8, 25) 2685*cda5da8dSAndroid Build Coastguard Worker >>> dist = 2 2686*cda5da8dSAndroid Build Coastguard Worker >>> for i in range(200): 2687*cda5da8dSAndroid Build Coastguard Worker ... turtle.fd(dist) 2688*cda5da8dSAndroid Build Coastguard Worker ... turtle.rt(90) 2689*cda5da8dSAndroid Build Coastguard Worker ... dist += 2 2690*cda5da8dSAndroid Build Coastguard Worker """ 2691*cda5da8dSAndroid Build Coastguard Worker return self.screen.tracer(flag, delay) 2692*cda5da8dSAndroid Build Coastguard Worker 2693*cda5da8dSAndroid Build Coastguard Worker def _color(self, args): 2694*cda5da8dSAndroid Build Coastguard Worker return self.screen._color(args) 2695*cda5da8dSAndroid Build Coastguard Worker 2696*cda5da8dSAndroid Build Coastguard Worker def _colorstr(self, args): 2697*cda5da8dSAndroid Build Coastguard Worker return self.screen._colorstr(args) 2698*cda5da8dSAndroid Build Coastguard Worker 2699*cda5da8dSAndroid Build Coastguard Worker def _cc(self, args): 2700*cda5da8dSAndroid Build Coastguard Worker """Convert colortriples to hexstrings. 2701*cda5da8dSAndroid Build Coastguard Worker """ 2702*cda5da8dSAndroid Build Coastguard Worker if isinstance(args, str): 2703*cda5da8dSAndroid Build Coastguard Worker return args 2704*cda5da8dSAndroid Build Coastguard Worker try: 2705*cda5da8dSAndroid Build Coastguard Worker r, g, b = args 2706*cda5da8dSAndroid Build Coastguard Worker except (TypeError, ValueError): 2707*cda5da8dSAndroid Build Coastguard Worker raise TurtleGraphicsError("bad color arguments: %s" % str(args)) 2708*cda5da8dSAndroid Build Coastguard Worker if self.screen._colormode == 1.0: 2709*cda5da8dSAndroid Build Coastguard Worker r, g, b = [round(255.0*x) for x in (r, g, b)] 2710*cda5da8dSAndroid Build Coastguard Worker if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)): 2711*cda5da8dSAndroid Build Coastguard Worker raise TurtleGraphicsError("bad color sequence: %s" % str(args)) 2712*cda5da8dSAndroid Build Coastguard Worker return "#%02x%02x%02x" % (r, g, b) 2713*cda5da8dSAndroid Build Coastguard Worker 2714*cda5da8dSAndroid Build Coastguard Worker def clone(self): 2715*cda5da8dSAndroid Build Coastguard Worker """Create and return a clone of the turtle. 2716*cda5da8dSAndroid Build Coastguard Worker 2717*cda5da8dSAndroid Build Coastguard Worker No argument. 2718*cda5da8dSAndroid Build Coastguard Worker 2719*cda5da8dSAndroid Build Coastguard Worker Create and return a clone of the turtle with same position, heading 2720*cda5da8dSAndroid Build Coastguard Worker and turtle properties. 2721*cda5da8dSAndroid Build Coastguard Worker 2722*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named mick): 2723*cda5da8dSAndroid Build Coastguard Worker mick = Turtle() 2724*cda5da8dSAndroid Build Coastguard Worker joe = mick.clone() 2725*cda5da8dSAndroid Build Coastguard Worker """ 2726*cda5da8dSAndroid Build Coastguard Worker screen = self.screen 2727*cda5da8dSAndroid Build Coastguard Worker self._newLine(self._drawing) 2728*cda5da8dSAndroid Build Coastguard Worker 2729*cda5da8dSAndroid Build Coastguard Worker turtle = self.turtle 2730*cda5da8dSAndroid Build Coastguard Worker self.screen = None 2731*cda5da8dSAndroid Build Coastguard Worker self.turtle = None # too make self deepcopy-able 2732*cda5da8dSAndroid Build Coastguard Worker 2733*cda5da8dSAndroid Build Coastguard Worker q = deepcopy(self) 2734*cda5da8dSAndroid Build Coastguard Worker 2735*cda5da8dSAndroid Build Coastguard Worker self.screen = screen 2736*cda5da8dSAndroid Build Coastguard Worker self.turtle = turtle 2737*cda5da8dSAndroid Build Coastguard Worker 2738*cda5da8dSAndroid Build Coastguard Worker q.screen = screen 2739*cda5da8dSAndroid Build Coastguard Worker q.turtle = _TurtleImage(screen, self.turtle.shapeIndex) 2740*cda5da8dSAndroid Build Coastguard Worker 2741*cda5da8dSAndroid Build Coastguard Worker screen._turtles.append(q) 2742*cda5da8dSAndroid Build Coastguard Worker ttype = screen._shapes[self.turtle.shapeIndex]._type 2743*cda5da8dSAndroid Build Coastguard Worker if ttype == "polygon": 2744*cda5da8dSAndroid Build Coastguard Worker q.turtle._item = screen._createpoly() 2745*cda5da8dSAndroid Build Coastguard Worker elif ttype == "image": 2746*cda5da8dSAndroid Build Coastguard Worker q.turtle._item = screen._createimage(screen._shapes["blank"]._data) 2747*cda5da8dSAndroid Build Coastguard Worker elif ttype == "compound": 2748*cda5da8dSAndroid Build Coastguard Worker q.turtle._item = [screen._createpoly() for item in 2749*cda5da8dSAndroid Build Coastguard Worker screen._shapes[self.turtle.shapeIndex]._data] 2750*cda5da8dSAndroid Build Coastguard Worker q.currentLineItem = screen._createline() 2751*cda5da8dSAndroid Build Coastguard Worker q._update() 2752*cda5da8dSAndroid Build Coastguard Worker return q 2753*cda5da8dSAndroid Build Coastguard Worker 2754*cda5da8dSAndroid Build Coastguard Worker def shape(self, name=None): 2755*cda5da8dSAndroid Build Coastguard Worker """Set turtle shape to shape with given name / return current shapename. 2756*cda5da8dSAndroid Build Coastguard Worker 2757*cda5da8dSAndroid Build Coastguard Worker Optional argument: 2758*cda5da8dSAndroid Build Coastguard Worker name -- a string, which is a valid shapename 2759*cda5da8dSAndroid Build Coastguard Worker 2760*cda5da8dSAndroid Build Coastguard Worker Set turtle shape to shape with given name or, if name is not given, 2761*cda5da8dSAndroid Build Coastguard Worker return name of current shape. 2762*cda5da8dSAndroid Build Coastguard Worker Shape with name must exist in the TurtleScreen's shape dictionary. 2763*cda5da8dSAndroid Build Coastguard Worker Initially there are the following polygon shapes: 2764*cda5da8dSAndroid Build Coastguard Worker 'arrow', 'turtle', 'circle', 'square', 'triangle', 'classic'. 2765*cda5da8dSAndroid Build Coastguard Worker To learn about how to deal with shapes see Screen-method register_shape. 2766*cda5da8dSAndroid Build Coastguard Worker 2767*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 2768*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shape() 2769*cda5da8dSAndroid Build Coastguard Worker 'arrow' 2770*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shape("turtle") 2771*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shape() 2772*cda5da8dSAndroid Build Coastguard Worker 'turtle' 2773*cda5da8dSAndroid Build Coastguard Worker """ 2774*cda5da8dSAndroid Build Coastguard Worker if name is None: 2775*cda5da8dSAndroid Build Coastguard Worker return self.turtle.shapeIndex 2776*cda5da8dSAndroid Build Coastguard Worker if not name in self.screen.getshapes(): 2777*cda5da8dSAndroid Build Coastguard Worker raise TurtleGraphicsError("There is no shape named %s" % name) 2778*cda5da8dSAndroid Build Coastguard Worker self.turtle._setshape(name) 2779*cda5da8dSAndroid Build Coastguard Worker self._update() 2780*cda5da8dSAndroid Build Coastguard Worker 2781*cda5da8dSAndroid Build Coastguard Worker def shapesize(self, stretch_wid=None, stretch_len=None, outline=None): 2782*cda5da8dSAndroid Build Coastguard Worker """Set/return turtle's stretchfactors/outline. Set resizemode to "user". 2783*cda5da8dSAndroid Build Coastguard Worker 2784*cda5da8dSAndroid Build Coastguard Worker Optional arguments: 2785*cda5da8dSAndroid Build Coastguard Worker stretch_wid : positive number 2786*cda5da8dSAndroid Build Coastguard Worker stretch_len : positive number 2787*cda5da8dSAndroid Build Coastguard Worker outline : positive number 2788*cda5da8dSAndroid Build Coastguard Worker 2789*cda5da8dSAndroid Build Coastguard Worker Return or set the pen's attributes x/y-stretchfactors and/or outline. 2790*cda5da8dSAndroid Build Coastguard Worker Set resizemode to "user". 2791*cda5da8dSAndroid Build Coastguard Worker If and only if resizemode is set to "user", the turtle will be displayed 2792*cda5da8dSAndroid Build Coastguard Worker stretched according to its stretchfactors: 2793*cda5da8dSAndroid Build Coastguard Worker stretch_wid is stretchfactor perpendicular to orientation 2794*cda5da8dSAndroid Build Coastguard Worker stretch_len is stretchfactor in direction of turtles orientation. 2795*cda5da8dSAndroid Build Coastguard Worker outline determines the width of the shapes's outline. 2796*cda5da8dSAndroid Build Coastguard Worker 2797*cda5da8dSAndroid Build Coastguard Worker Examples (for a Turtle instance named turtle): 2798*cda5da8dSAndroid Build Coastguard Worker >>> turtle.resizemode("user") 2799*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shapesize(5, 5, 12) 2800*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shapesize(outline=8) 2801*cda5da8dSAndroid Build Coastguard Worker """ 2802*cda5da8dSAndroid Build Coastguard Worker if stretch_wid is stretch_len is outline is None: 2803*cda5da8dSAndroid Build Coastguard Worker stretch_wid, stretch_len = self._stretchfactor 2804*cda5da8dSAndroid Build Coastguard Worker return stretch_wid, stretch_len, self._outlinewidth 2805*cda5da8dSAndroid Build Coastguard Worker if stretch_wid == 0 or stretch_len == 0: 2806*cda5da8dSAndroid Build Coastguard Worker raise TurtleGraphicsError("stretch_wid/stretch_len must not be zero") 2807*cda5da8dSAndroid Build Coastguard Worker if stretch_wid is not None: 2808*cda5da8dSAndroid Build Coastguard Worker if stretch_len is None: 2809*cda5da8dSAndroid Build Coastguard Worker stretchfactor = stretch_wid, stretch_wid 2810*cda5da8dSAndroid Build Coastguard Worker else: 2811*cda5da8dSAndroid Build Coastguard Worker stretchfactor = stretch_wid, stretch_len 2812*cda5da8dSAndroid Build Coastguard Worker elif stretch_len is not None: 2813*cda5da8dSAndroid Build Coastguard Worker stretchfactor = self._stretchfactor[0], stretch_len 2814*cda5da8dSAndroid Build Coastguard Worker else: 2815*cda5da8dSAndroid Build Coastguard Worker stretchfactor = self._stretchfactor 2816*cda5da8dSAndroid Build Coastguard Worker if outline is None: 2817*cda5da8dSAndroid Build Coastguard Worker outline = self._outlinewidth 2818*cda5da8dSAndroid Build Coastguard Worker self.pen(resizemode="user", 2819*cda5da8dSAndroid Build Coastguard Worker stretchfactor=stretchfactor, outline=outline) 2820*cda5da8dSAndroid Build Coastguard Worker 2821*cda5da8dSAndroid Build Coastguard Worker def shearfactor(self, shear=None): 2822*cda5da8dSAndroid Build Coastguard Worker """Set or return the current shearfactor. 2823*cda5da8dSAndroid Build Coastguard Worker 2824*cda5da8dSAndroid Build Coastguard Worker Optional argument: shear -- number, tangent of the shear angle 2825*cda5da8dSAndroid Build Coastguard Worker 2826*cda5da8dSAndroid Build Coastguard Worker Shear the turtleshape according to the given shearfactor shear, 2827*cda5da8dSAndroid Build Coastguard Worker which is the tangent of the shear angle. DO NOT change the 2828*cda5da8dSAndroid Build Coastguard Worker turtle's heading (direction of movement). 2829*cda5da8dSAndroid Build Coastguard Worker If shear is not given: return the current shearfactor, i. e. the 2830*cda5da8dSAndroid Build Coastguard Worker tangent of the shear angle, by which lines parallel to the 2831*cda5da8dSAndroid Build Coastguard Worker heading of the turtle are sheared. 2832*cda5da8dSAndroid Build Coastguard Worker 2833*cda5da8dSAndroid Build Coastguard Worker Examples (for a Turtle instance named turtle): 2834*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shape("circle") 2835*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shapesize(5,2) 2836*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shearfactor(0.5) 2837*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shearfactor() 2838*cda5da8dSAndroid Build Coastguard Worker >>> 0.5 2839*cda5da8dSAndroid Build Coastguard Worker """ 2840*cda5da8dSAndroid Build Coastguard Worker if shear is None: 2841*cda5da8dSAndroid Build Coastguard Worker return self._shearfactor 2842*cda5da8dSAndroid Build Coastguard Worker self.pen(resizemode="user", shearfactor=shear) 2843*cda5da8dSAndroid Build Coastguard Worker 2844*cda5da8dSAndroid Build Coastguard Worker def settiltangle(self, angle): 2845*cda5da8dSAndroid Build Coastguard Worker """Rotate the turtleshape to point in the specified direction 2846*cda5da8dSAndroid Build Coastguard Worker 2847*cda5da8dSAndroid Build Coastguard Worker Argument: angle -- number 2848*cda5da8dSAndroid Build Coastguard Worker 2849*cda5da8dSAndroid Build Coastguard Worker Rotate the turtleshape to point in the direction specified by angle, 2850*cda5da8dSAndroid Build Coastguard Worker regardless of its current tilt-angle. DO NOT change the turtle's 2851*cda5da8dSAndroid Build Coastguard Worker heading (direction of movement). 2852*cda5da8dSAndroid Build Coastguard Worker 2853*cda5da8dSAndroid Build Coastguard Worker Deprecated since Python 3.1 2854*cda5da8dSAndroid Build Coastguard Worker 2855*cda5da8dSAndroid Build Coastguard Worker Examples (for a Turtle instance named turtle): 2856*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shape("circle") 2857*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shapesize(5,2) 2858*cda5da8dSAndroid Build Coastguard Worker >>> turtle.settiltangle(45) 2859*cda5da8dSAndroid Build Coastguard Worker >>> turtle.stamp() 2860*cda5da8dSAndroid Build Coastguard Worker >>> turtle.fd(50) 2861*cda5da8dSAndroid Build Coastguard Worker >>> turtle.settiltangle(-45) 2862*cda5da8dSAndroid Build Coastguard Worker >>> turtle.stamp() 2863*cda5da8dSAndroid Build Coastguard Worker >>> turtle.fd(50) 2864*cda5da8dSAndroid Build Coastguard Worker """ 2865*cda5da8dSAndroid Build Coastguard Worker warnings._deprecated("turtle.RawTurtle.settiltangle()", 2866*cda5da8dSAndroid Build Coastguard Worker "{name!r} is deprecated since Python 3.1 and scheduled " 2867*cda5da8dSAndroid Build Coastguard Worker "for removal in Python {remove}. Use tiltangle() instead.", 2868*cda5da8dSAndroid Build Coastguard Worker remove=(3, 13)) 2869*cda5da8dSAndroid Build Coastguard Worker self.tiltangle(angle) 2870*cda5da8dSAndroid Build Coastguard Worker 2871*cda5da8dSAndroid Build Coastguard Worker def tiltangle(self, angle=None): 2872*cda5da8dSAndroid Build Coastguard Worker """Set or return the current tilt-angle. 2873*cda5da8dSAndroid Build Coastguard Worker 2874*cda5da8dSAndroid Build Coastguard Worker Optional argument: angle -- number 2875*cda5da8dSAndroid Build Coastguard Worker 2876*cda5da8dSAndroid Build Coastguard Worker Rotate the turtleshape to point in the direction specified by angle, 2877*cda5da8dSAndroid Build Coastguard Worker regardless of its current tilt-angle. DO NOT change the turtle's 2878*cda5da8dSAndroid Build Coastguard Worker heading (direction of movement). 2879*cda5da8dSAndroid Build Coastguard Worker If angle is not given: return the current tilt-angle, i. e. the angle 2880*cda5da8dSAndroid Build Coastguard Worker between the orientation of the turtleshape and the heading of the 2881*cda5da8dSAndroid Build Coastguard Worker turtle (its direction of movement). 2882*cda5da8dSAndroid Build Coastguard Worker 2883*cda5da8dSAndroid Build Coastguard Worker (Incorrectly marked as deprecated since Python 3.1, it is really 2884*cda5da8dSAndroid Build Coastguard Worker settiltangle that is deprecated.) 2885*cda5da8dSAndroid Build Coastguard Worker 2886*cda5da8dSAndroid Build Coastguard Worker Examples (for a Turtle instance named turtle): 2887*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shape("circle") 2888*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shapesize(5, 2) 2889*cda5da8dSAndroid Build Coastguard Worker >>> turtle.tiltangle() 2890*cda5da8dSAndroid Build Coastguard Worker 0.0 2891*cda5da8dSAndroid Build Coastguard Worker >>> turtle.tiltangle(45) 2892*cda5da8dSAndroid Build Coastguard Worker >>> turtle.tiltangle() 2893*cda5da8dSAndroid Build Coastguard Worker 45.0 2894*cda5da8dSAndroid Build Coastguard Worker >>> turtle.stamp() 2895*cda5da8dSAndroid Build Coastguard Worker >>> turtle.fd(50) 2896*cda5da8dSAndroid Build Coastguard Worker >>> turtle.tiltangle(-45) 2897*cda5da8dSAndroid Build Coastguard Worker >>> turtle.tiltangle() 2898*cda5da8dSAndroid Build Coastguard Worker 315.0 2899*cda5da8dSAndroid Build Coastguard Worker >>> turtle.stamp() 2900*cda5da8dSAndroid Build Coastguard Worker >>> turtle.fd(50) 2901*cda5da8dSAndroid Build Coastguard Worker """ 2902*cda5da8dSAndroid Build Coastguard Worker if angle is None: 2903*cda5da8dSAndroid Build Coastguard Worker tilt = -math.degrees(self._tilt) * self._angleOrient 2904*cda5da8dSAndroid Build Coastguard Worker return (tilt / self._degreesPerAU) % self._fullcircle 2905*cda5da8dSAndroid Build Coastguard Worker else: 2906*cda5da8dSAndroid Build Coastguard Worker tilt = -angle * self._degreesPerAU * self._angleOrient 2907*cda5da8dSAndroid Build Coastguard Worker tilt = math.radians(tilt) % math.tau 2908*cda5da8dSAndroid Build Coastguard Worker self.pen(resizemode="user", tilt=tilt) 2909*cda5da8dSAndroid Build Coastguard Worker 2910*cda5da8dSAndroid Build Coastguard Worker def tilt(self, angle): 2911*cda5da8dSAndroid Build Coastguard Worker """Rotate the turtleshape by angle. 2912*cda5da8dSAndroid Build Coastguard Worker 2913*cda5da8dSAndroid Build Coastguard Worker Argument: 2914*cda5da8dSAndroid Build Coastguard Worker angle - a number 2915*cda5da8dSAndroid Build Coastguard Worker 2916*cda5da8dSAndroid Build Coastguard Worker Rotate the turtleshape by angle from its current tilt-angle, 2917*cda5da8dSAndroid Build Coastguard Worker but do NOT change the turtle's heading (direction of movement). 2918*cda5da8dSAndroid Build Coastguard Worker 2919*cda5da8dSAndroid Build Coastguard Worker Examples (for a Turtle instance named turtle): 2920*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shape("circle") 2921*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shapesize(5,2) 2922*cda5da8dSAndroid Build Coastguard Worker >>> turtle.tilt(30) 2923*cda5da8dSAndroid Build Coastguard Worker >>> turtle.fd(50) 2924*cda5da8dSAndroid Build Coastguard Worker >>> turtle.tilt(30) 2925*cda5da8dSAndroid Build Coastguard Worker >>> turtle.fd(50) 2926*cda5da8dSAndroid Build Coastguard Worker """ 2927*cda5da8dSAndroid Build Coastguard Worker self.tiltangle(angle + self.tiltangle()) 2928*cda5da8dSAndroid Build Coastguard Worker 2929*cda5da8dSAndroid Build Coastguard Worker def shapetransform(self, t11=None, t12=None, t21=None, t22=None): 2930*cda5da8dSAndroid Build Coastguard Worker """Set or return the current transformation matrix of the turtle shape. 2931*cda5da8dSAndroid Build Coastguard Worker 2932*cda5da8dSAndroid Build Coastguard Worker Optional arguments: t11, t12, t21, t22 -- numbers. 2933*cda5da8dSAndroid Build Coastguard Worker 2934*cda5da8dSAndroid Build Coastguard Worker If none of the matrix elements are given, return the transformation 2935*cda5da8dSAndroid Build Coastguard Worker matrix. 2936*cda5da8dSAndroid Build Coastguard Worker Otherwise set the given elements and transform the turtleshape 2937*cda5da8dSAndroid Build Coastguard Worker according to the matrix consisting of first row t11, t12 and 2938*cda5da8dSAndroid Build Coastguard Worker second row t21, 22. 2939*cda5da8dSAndroid Build Coastguard Worker Modify stretchfactor, shearfactor and tiltangle according to the 2940*cda5da8dSAndroid Build Coastguard Worker given matrix. 2941*cda5da8dSAndroid Build Coastguard Worker 2942*cda5da8dSAndroid Build Coastguard Worker Examples (for a Turtle instance named turtle): 2943*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shape("square") 2944*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shapesize(4,2) 2945*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shearfactor(-0.5) 2946*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shapetransform() 2947*cda5da8dSAndroid Build Coastguard Worker (4.0, -1.0, -0.0, 2.0) 2948*cda5da8dSAndroid Build Coastguard Worker """ 2949*cda5da8dSAndroid Build Coastguard Worker if t11 is t12 is t21 is t22 is None: 2950*cda5da8dSAndroid Build Coastguard Worker return self._shapetrafo 2951*cda5da8dSAndroid Build Coastguard Worker m11, m12, m21, m22 = self._shapetrafo 2952*cda5da8dSAndroid Build Coastguard Worker if t11 is not None: m11 = t11 2953*cda5da8dSAndroid Build Coastguard Worker if t12 is not None: m12 = t12 2954*cda5da8dSAndroid Build Coastguard Worker if t21 is not None: m21 = t21 2955*cda5da8dSAndroid Build Coastguard Worker if t22 is not None: m22 = t22 2956*cda5da8dSAndroid Build Coastguard Worker if t11 * t22 - t12 * t21 == 0: 2957*cda5da8dSAndroid Build Coastguard Worker raise TurtleGraphicsError("Bad shape transform matrix: must not be singular") 2958*cda5da8dSAndroid Build Coastguard Worker self._shapetrafo = (m11, m12, m21, m22) 2959*cda5da8dSAndroid Build Coastguard Worker alfa = math.atan2(-m21, m11) % math.tau 2960*cda5da8dSAndroid Build Coastguard Worker sa, ca = math.sin(alfa), math.cos(alfa) 2961*cda5da8dSAndroid Build Coastguard Worker a11, a12, a21, a22 = (ca*m11 - sa*m21, ca*m12 - sa*m22, 2962*cda5da8dSAndroid Build Coastguard Worker sa*m11 + ca*m21, sa*m12 + ca*m22) 2963*cda5da8dSAndroid Build Coastguard Worker self._stretchfactor = a11, a22 2964*cda5da8dSAndroid Build Coastguard Worker self._shearfactor = a12/a22 2965*cda5da8dSAndroid Build Coastguard Worker self._tilt = alfa 2966*cda5da8dSAndroid Build Coastguard Worker self.pen(resizemode="user") 2967*cda5da8dSAndroid Build Coastguard Worker 2968*cda5da8dSAndroid Build Coastguard Worker 2969*cda5da8dSAndroid Build Coastguard Worker def _polytrafo(self, poly): 2970*cda5da8dSAndroid Build Coastguard Worker """Computes transformed polygon shapes from a shape 2971*cda5da8dSAndroid Build Coastguard Worker according to current position and heading. 2972*cda5da8dSAndroid Build Coastguard Worker """ 2973*cda5da8dSAndroid Build Coastguard Worker screen = self.screen 2974*cda5da8dSAndroid Build Coastguard Worker p0, p1 = self._position 2975*cda5da8dSAndroid Build Coastguard Worker e0, e1 = self._orient 2976*cda5da8dSAndroid Build Coastguard Worker e = Vec2D(e0, e1 * screen.yscale / screen.xscale) 2977*cda5da8dSAndroid Build Coastguard Worker e0, e1 = (1.0 / abs(e)) * e 2978*cda5da8dSAndroid Build Coastguard Worker return [(p0+(e1*x+e0*y)/screen.xscale, p1+(-e0*x+e1*y)/screen.yscale) 2979*cda5da8dSAndroid Build Coastguard Worker for (x, y) in poly] 2980*cda5da8dSAndroid Build Coastguard Worker 2981*cda5da8dSAndroid Build Coastguard Worker def get_shapepoly(self): 2982*cda5da8dSAndroid Build Coastguard Worker """Return the current shape polygon as tuple of coordinate pairs. 2983*cda5da8dSAndroid Build Coastguard Worker 2984*cda5da8dSAndroid Build Coastguard Worker No argument. 2985*cda5da8dSAndroid Build Coastguard Worker 2986*cda5da8dSAndroid Build Coastguard Worker Examples (for a Turtle instance named turtle): 2987*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shape("square") 2988*cda5da8dSAndroid Build Coastguard Worker >>> turtle.shapetransform(4, -1, 0, 2) 2989*cda5da8dSAndroid Build Coastguard Worker >>> turtle.get_shapepoly() 2990*cda5da8dSAndroid Build Coastguard Worker ((50, -20), (30, 20), (-50, 20), (-30, -20)) 2991*cda5da8dSAndroid Build Coastguard Worker 2992*cda5da8dSAndroid Build Coastguard Worker """ 2993*cda5da8dSAndroid Build Coastguard Worker shape = self.screen._shapes[self.turtle.shapeIndex] 2994*cda5da8dSAndroid Build Coastguard Worker if shape._type == "polygon": 2995*cda5da8dSAndroid Build Coastguard Worker return self._getshapepoly(shape._data, shape._type == "compound") 2996*cda5da8dSAndroid Build Coastguard Worker # else return None 2997*cda5da8dSAndroid Build Coastguard Worker 2998*cda5da8dSAndroid Build Coastguard Worker def _getshapepoly(self, polygon, compound=False): 2999*cda5da8dSAndroid Build Coastguard Worker """Calculate transformed shape polygon according to resizemode 3000*cda5da8dSAndroid Build Coastguard Worker and shapetransform. 3001*cda5da8dSAndroid Build Coastguard Worker """ 3002*cda5da8dSAndroid Build Coastguard Worker if self._resizemode == "user" or compound: 3003*cda5da8dSAndroid Build Coastguard Worker t11, t12, t21, t22 = self._shapetrafo 3004*cda5da8dSAndroid Build Coastguard Worker elif self._resizemode == "auto": 3005*cda5da8dSAndroid Build Coastguard Worker l = max(1, self._pensize/5.0) 3006*cda5da8dSAndroid Build Coastguard Worker t11, t12, t21, t22 = l, 0, 0, l 3007*cda5da8dSAndroid Build Coastguard Worker elif self._resizemode == "noresize": 3008*cda5da8dSAndroid Build Coastguard Worker return polygon 3009*cda5da8dSAndroid Build Coastguard Worker return tuple((t11*x + t12*y, t21*x + t22*y) for (x, y) in polygon) 3010*cda5da8dSAndroid Build Coastguard Worker 3011*cda5da8dSAndroid Build Coastguard Worker def _drawturtle(self): 3012*cda5da8dSAndroid Build Coastguard Worker """Manages the correct rendering of the turtle with respect to 3013*cda5da8dSAndroid Build Coastguard Worker its shape, resizemode, stretch and tilt etc.""" 3014*cda5da8dSAndroid Build Coastguard Worker screen = self.screen 3015*cda5da8dSAndroid Build Coastguard Worker shape = screen._shapes[self.turtle.shapeIndex] 3016*cda5da8dSAndroid Build Coastguard Worker ttype = shape._type 3017*cda5da8dSAndroid Build Coastguard Worker titem = self.turtle._item 3018*cda5da8dSAndroid Build Coastguard Worker if self._shown and screen._updatecounter == 0 and screen._tracing > 0: 3019*cda5da8dSAndroid Build Coastguard Worker self._hidden_from_screen = False 3020*cda5da8dSAndroid Build Coastguard Worker tshape = shape._data 3021*cda5da8dSAndroid Build Coastguard Worker if ttype == "polygon": 3022*cda5da8dSAndroid Build Coastguard Worker if self._resizemode == "noresize": w = 1 3023*cda5da8dSAndroid Build Coastguard Worker elif self._resizemode == "auto": w = self._pensize 3024*cda5da8dSAndroid Build Coastguard Worker else: w =self._outlinewidth 3025*cda5da8dSAndroid Build Coastguard Worker shape = self._polytrafo(self._getshapepoly(tshape)) 3026*cda5da8dSAndroid Build Coastguard Worker fc, oc = self._fillcolor, self._pencolor 3027*cda5da8dSAndroid Build Coastguard Worker screen._drawpoly(titem, shape, fill=fc, outline=oc, 3028*cda5da8dSAndroid Build Coastguard Worker width=w, top=True) 3029*cda5da8dSAndroid Build Coastguard Worker elif ttype == "image": 3030*cda5da8dSAndroid Build Coastguard Worker screen._drawimage(titem, self._position, tshape) 3031*cda5da8dSAndroid Build Coastguard Worker elif ttype == "compound": 3032*cda5da8dSAndroid Build Coastguard Worker for item, (poly, fc, oc) in zip(titem, tshape): 3033*cda5da8dSAndroid Build Coastguard Worker poly = self._polytrafo(self._getshapepoly(poly, True)) 3034*cda5da8dSAndroid Build Coastguard Worker screen._drawpoly(item, poly, fill=self._cc(fc), 3035*cda5da8dSAndroid Build Coastguard Worker outline=self._cc(oc), width=self._outlinewidth, top=True) 3036*cda5da8dSAndroid Build Coastguard Worker else: 3037*cda5da8dSAndroid Build Coastguard Worker if self._hidden_from_screen: 3038*cda5da8dSAndroid Build Coastguard Worker return 3039*cda5da8dSAndroid Build Coastguard Worker if ttype == "polygon": 3040*cda5da8dSAndroid Build Coastguard Worker screen._drawpoly(titem, ((0, 0), (0, 0), (0, 0)), "", "") 3041*cda5da8dSAndroid Build Coastguard Worker elif ttype == "image": 3042*cda5da8dSAndroid Build Coastguard Worker screen._drawimage(titem, self._position, 3043*cda5da8dSAndroid Build Coastguard Worker screen._shapes["blank"]._data) 3044*cda5da8dSAndroid Build Coastguard Worker elif ttype == "compound": 3045*cda5da8dSAndroid Build Coastguard Worker for item in titem: 3046*cda5da8dSAndroid Build Coastguard Worker screen._drawpoly(item, ((0, 0), (0, 0), (0, 0)), "", "") 3047*cda5da8dSAndroid Build Coastguard Worker self._hidden_from_screen = True 3048*cda5da8dSAndroid Build Coastguard Worker 3049*cda5da8dSAndroid Build Coastguard Worker############################## stamp stuff ############################### 3050*cda5da8dSAndroid Build Coastguard Worker 3051*cda5da8dSAndroid Build Coastguard Worker def stamp(self): 3052*cda5da8dSAndroid Build Coastguard Worker """Stamp a copy of the turtleshape onto the canvas and return its id. 3053*cda5da8dSAndroid Build Coastguard Worker 3054*cda5da8dSAndroid Build Coastguard Worker No argument. 3055*cda5da8dSAndroid Build Coastguard Worker 3056*cda5da8dSAndroid Build Coastguard Worker Stamp a copy of the turtle shape onto the canvas at the current 3057*cda5da8dSAndroid Build Coastguard Worker turtle position. Return a stamp_id for that stamp, which can be 3058*cda5da8dSAndroid Build Coastguard Worker used to delete it by calling clearstamp(stamp_id). 3059*cda5da8dSAndroid Build Coastguard Worker 3060*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 3061*cda5da8dSAndroid Build Coastguard Worker >>> turtle.color("blue") 3062*cda5da8dSAndroid Build Coastguard Worker >>> turtle.stamp() 3063*cda5da8dSAndroid Build Coastguard Worker 13 3064*cda5da8dSAndroid Build Coastguard Worker >>> turtle.fd(50) 3065*cda5da8dSAndroid Build Coastguard Worker """ 3066*cda5da8dSAndroid Build Coastguard Worker screen = self.screen 3067*cda5da8dSAndroid Build Coastguard Worker shape = screen._shapes[self.turtle.shapeIndex] 3068*cda5da8dSAndroid Build Coastguard Worker ttype = shape._type 3069*cda5da8dSAndroid Build Coastguard Worker tshape = shape._data 3070*cda5da8dSAndroid Build Coastguard Worker if ttype == "polygon": 3071*cda5da8dSAndroid Build Coastguard Worker stitem = screen._createpoly() 3072*cda5da8dSAndroid Build Coastguard Worker if self._resizemode == "noresize": w = 1 3073*cda5da8dSAndroid Build Coastguard Worker elif self._resizemode == "auto": w = self._pensize 3074*cda5da8dSAndroid Build Coastguard Worker else: w =self._outlinewidth 3075*cda5da8dSAndroid Build Coastguard Worker shape = self._polytrafo(self._getshapepoly(tshape)) 3076*cda5da8dSAndroid Build Coastguard Worker fc, oc = self._fillcolor, self._pencolor 3077*cda5da8dSAndroid Build Coastguard Worker screen._drawpoly(stitem, shape, fill=fc, outline=oc, 3078*cda5da8dSAndroid Build Coastguard Worker width=w, top=True) 3079*cda5da8dSAndroid Build Coastguard Worker elif ttype == "image": 3080*cda5da8dSAndroid Build Coastguard Worker stitem = screen._createimage("") 3081*cda5da8dSAndroid Build Coastguard Worker screen._drawimage(stitem, self._position, tshape) 3082*cda5da8dSAndroid Build Coastguard Worker elif ttype == "compound": 3083*cda5da8dSAndroid Build Coastguard Worker stitem = [] 3084*cda5da8dSAndroid Build Coastguard Worker for element in tshape: 3085*cda5da8dSAndroid Build Coastguard Worker item = screen._createpoly() 3086*cda5da8dSAndroid Build Coastguard Worker stitem.append(item) 3087*cda5da8dSAndroid Build Coastguard Worker stitem = tuple(stitem) 3088*cda5da8dSAndroid Build Coastguard Worker for item, (poly, fc, oc) in zip(stitem, tshape): 3089*cda5da8dSAndroid Build Coastguard Worker poly = self._polytrafo(self._getshapepoly(poly, True)) 3090*cda5da8dSAndroid Build Coastguard Worker screen._drawpoly(item, poly, fill=self._cc(fc), 3091*cda5da8dSAndroid Build Coastguard Worker outline=self._cc(oc), width=self._outlinewidth, top=True) 3092*cda5da8dSAndroid Build Coastguard Worker self.stampItems.append(stitem) 3093*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.push(("stamp", stitem)) 3094*cda5da8dSAndroid Build Coastguard Worker return stitem 3095*cda5da8dSAndroid Build Coastguard Worker 3096*cda5da8dSAndroid Build Coastguard Worker def _clearstamp(self, stampid): 3097*cda5da8dSAndroid Build Coastguard Worker """does the work for clearstamp() and clearstamps() 3098*cda5da8dSAndroid Build Coastguard Worker """ 3099*cda5da8dSAndroid Build Coastguard Worker if stampid in self.stampItems: 3100*cda5da8dSAndroid Build Coastguard Worker if isinstance(stampid, tuple): 3101*cda5da8dSAndroid Build Coastguard Worker for subitem in stampid: 3102*cda5da8dSAndroid Build Coastguard Worker self.screen._delete(subitem) 3103*cda5da8dSAndroid Build Coastguard Worker else: 3104*cda5da8dSAndroid Build Coastguard Worker self.screen._delete(stampid) 3105*cda5da8dSAndroid Build Coastguard Worker self.stampItems.remove(stampid) 3106*cda5da8dSAndroid Build Coastguard Worker # Delete stampitem from undobuffer if necessary 3107*cda5da8dSAndroid Build Coastguard Worker # if clearstamp is called directly. 3108*cda5da8dSAndroid Build Coastguard Worker item = ("stamp", stampid) 3109*cda5da8dSAndroid Build Coastguard Worker buf = self.undobuffer 3110*cda5da8dSAndroid Build Coastguard Worker if item not in buf.buffer: 3111*cda5da8dSAndroid Build Coastguard Worker return 3112*cda5da8dSAndroid Build Coastguard Worker index = buf.buffer.index(item) 3113*cda5da8dSAndroid Build Coastguard Worker buf.buffer.remove(item) 3114*cda5da8dSAndroid Build Coastguard Worker if index <= buf.ptr: 3115*cda5da8dSAndroid Build Coastguard Worker buf.ptr = (buf.ptr - 1) % buf.bufsize 3116*cda5da8dSAndroid Build Coastguard Worker buf.buffer.insert((buf.ptr+1)%buf.bufsize, [None]) 3117*cda5da8dSAndroid Build Coastguard Worker 3118*cda5da8dSAndroid Build Coastguard Worker def clearstamp(self, stampid): 3119*cda5da8dSAndroid Build Coastguard Worker """Delete stamp with given stampid 3120*cda5da8dSAndroid Build Coastguard Worker 3121*cda5da8dSAndroid Build Coastguard Worker Argument: 3122*cda5da8dSAndroid Build Coastguard Worker stampid - an integer, must be return value of previous stamp() call. 3123*cda5da8dSAndroid Build Coastguard Worker 3124*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 3125*cda5da8dSAndroid Build Coastguard Worker >>> turtle.color("blue") 3126*cda5da8dSAndroid Build Coastguard Worker >>> astamp = turtle.stamp() 3127*cda5da8dSAndroid Build Coastguard Worker >>> turtle.fd(50) 3128*cda5da8dSAndroid Build Coastguard Worker >>> turtle.clearstamp(astamp) 3129*cda5da8dSAndroid Build Coastguard Worker """ 3130*cda5da8dSAndroid Build Coastguard Worker self._clearstamp(stampid) 3131*cda5da8dSAndroid Build Coastguard Worker self._update() 3132*cda5da8dSAndroid Build Coastguard Worker 3133*cda5da8dSAndroid Build Coastguard Worker def clearstamps(self, n=None): 3134*cda5da8dSAndroid Build Coastguard Worker """Delete all or first/last n of turtle's stamps. 3135*cda5da8dSAndroid Build Coastguard Worker 3136*cda5da8dSAndroid Build Coastguard Worker Optional argument: 3137*cda5da8dSAndroid Build Coastguard Worker n -- an integer 3138*cda5da8dSAndroid Build Coastguard Worker 3139*cda5da8dSAndroid Build Coastguard Worker If n is None, delete all of pen's stamps, 3140*cda5da8dSAndroid Build Coastguard Worker else if n > 0 delete first n stamps 3141*cda5da8dSAndroid Build Coastguard Worker else if n < 0 delete last n stamps. 3142*cda5da8dSAndroid Build Coastguard Worker 3143*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 3144*cda5da8dSAndroid Build Coastguard Worker >>> for i in range(8): 3145*cda5da8dSAndroid Build Coastguard Worker ... turtle.stamp(); turtle.fd(30) 3146*cda5da8dSAndroid Build Coastguard Worker ... 3147*cda5da8dSAndroid Build Coastguard Worker >>> turtle.clearstamps(2) 3148*cda5da8dSAndroid Build Coastguard Worker >>> turtle.clearstamps(-2) 3149*cda5da8dSAndroid Build Coastguard Worker >>> turtle.clearstamps() 3150*cda5da8dSAndroid Build Coastguard Worker """ 3151*cda5da8dSAndroid Build Coastguard Worker if n is None: 3152*cda5da8dSAndroid Build Coastguard Worker toDelete = self.stampItems[:] 3153*cda5da8dSAndroid Build Coastguard Worker elif n >= 0: 3154*cda5da8dSAndroid Build Coastguard Worker toDelete = self.stampItems[:n] 3155*cda5da8dSAndroid Build Coastguard Worker else: 3156*cda5da8dSAndroid Build Coastguard Worker toDelete = self.stampItems[n:] 3157*cda5da8dSAndroid Build Coastguard Worker for item in toDelete: 3158*cda5da8dSAndroid Build Coastguard Worker self._clearstamp(item) 3159*cda5da8dSAndroid Build Coastguard Worker self._update() 3160*cda5da8dSAndroid Build Coastguard Worker 3161*cda5da8dSAndroid Build Coastguard Worker def _goto(self, end): 3162*cda5da8dSAndroid Build Coastguard Worker """Move the pen to the point end, thereby drawing a line 3163*cda5da8dSAndroid Build Coastguard Worker if pen is down. All other methods for turtle movement depend 3164*cda5da8dSAndroid Build Coastguard Worker on this one. 3165*cda5da8dSAndroid Build Coastguard Worker """ 3166*cda5da8dSAndroid Build Coastguard Worker ## Version with undo-stuff 3167*cda5da8dSAndroid Build Coastguard Worker go_modes = ( self._drawing, 3168*cda5da8dSAndroid Build Coastguard Worker self._pencolor, 3169*cda5da8dSAndroid Build Coastguard Worker self._pensize, 3170*cda5da8dSAndroid Build Coastguard Worker isinstance(self._fillpath, list)) 3171*cda5da8dSAndroid Build Coastguard Worker screen = self.screen 3172*cda5da8dSAndroid Build Coastguard Worker undo_entry = ("go", self._position, end, go_modes, 3173*cda5da8dSAndroid Build Coastguard Worker (self.currentLineItem, 3174*cda5da8dSAndroid Build Coastguard Worker self.currentLine[:], 3175*cda5da8dSAndroid Build Coastguard Worker screen._pointlist(self.currentLineItem), 3176*cda5da8dSAndroid Build Coastguard Worker self.items[:]) 3177*cda5da8dSAndroid Build Coastguard Worker ) 3178*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer: 3179*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.push(undo_entry) 3180*cda5da8dSAndroid Build Coastguard Worker start = self._position 3181*cda5da8dSAndroid Build Coastguard Worker if self._speed and screen._tracing == 1: 3182*cda5da8dSAndroid Build Coastguard Worker diff = (end-start) 3183*cda5da8dSAndroid Build Coastguard Worker diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2 3184*cda5da8dSAndroid Build Coastguard Worker nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed)) 3185*cda5da8dSAndroid Build Coastguard Worker delta = diff * (1.0/nhops) 3186*cda5da8dSAndroid Build Coastguard Worker for n in range(1, nhops): 3187*cda5da8dSAndroid Build Coastguard Worker if n == 1: 3188*cda5da8dSAndroid Build Coastguard Worker top = True 3189*cda5da8dSAndroid Build Coastguard Worker else: 3190*cda5da8dSAndroid Build Coastguard Worker top = False 3191*cda5da8dSAndroid Build Coastguard Worker self._position = start + delta * n 3192*cda5da8dSAndroid Build Coastguard Worker if self._drawing: 3193*cda5da8dSAndroid Build Coastguard Worker screen._drawline(self.drawingLineItem, 3194*cda5da8dSAndroid Build Coastguard Worker (start, self._position), 3195*cda5da8dSAndroid Build Coastguard Worker self._pencolor, self._pensize, top) 3196*cda5da8dSAndroid Build Coastguard Worker self._update() 3197*cda5da8dSAndroid Build Coastguard Worker if self._drawing: 3198*cda5da8dSAndroid Build Coastguard Worker screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)), 3199*cda5da8dSAndroid Build Coastguard Worker fill="", width=self._pensize) 3200*cda5da8dSAndroid Build Coastguard Worker # Turtle now at end, 3201*cda5da8dSAndroid Build Coastguard Worker if self._drawing: # now update currentLine 3202*cda5da8dSAndroid Build Coastguard Worker self.currentLine.append(end) 3203*cda5da8dSAndroid Build Coastguard Worker if isinstance(self._fillpath, list): 3204*cda5da8dSAndroid Build Coastguard Worker self._fillpath.append(end) 3205*cda5da8dSAndroid Build Coastguard Worker ###### vererbung!!!!!!!!!!!!!!!!!!!!!! 3206*cda5da8dSAndroid Build Coastguard Worker self._position = end 3207*cda5da8dSAndroid Build Coastguard Worker if self._creatingPoly: 3208*cda5da8dSAndroid Build Coastguard Worker self._poly.append(end) 3209*cda5da8dSAndroid Build Coastguard Worker if len(self.currentLine) > 42: # 42! answer to the ultimate question 3210*cda5da8dSAndroid Build Coastguard Worker # of life, the universe and everything 3211*cda5da8dSAndroid Build Coastguard Worker self._newLine() 3212*cda5da8dSAndroid Build Coastguard Worker self._update() #count=True) 3213*cda5da8dSAndroid Build Coastguard Worker 3214*cda5da8dSAndroid Build Coastguard Worker def _undogoto(self, entry): 3215*cda5da8dSAndroid Build Coastguard Worker """Reverse a _goto. Used for undo() 3216*cda5da8dSAndroid Build Coastguard Worker """ 3217*cda5da8dSAndroid Build Coastguard Worker old, new, go_modes, coodata = entry 3218*cda5da8dSAndroid Build Coastguard Worker drawing, pc, ps, filling = go_modes 3219*cda5da8dSAndroid Build Coastguard Worker cLI, cL, pl, items = coodata 3220*cda5da8dSAndroid Build Coastguard Worker screen = self.screen 3221*cda5da8dSAndroid Build Coastguard Worker if abs(self._position - new) > 0.5: 3222*cda5da8dSAndroid Build Coastguard Worker print ("undogoto: HALLO-DA-STIMMT-WAS-NICHT!") 3223*cda5da8dSAndroid Build Coastguard Worker # restore former situation 3224*cda5da8dSAndroid Build Coastguard Worker self.currentLineItem = cLI 3225*cda5da8dSAndroid Build Coastguard Worker self.currentLine = cL 3226*cda5da8dSAndroid Build Coastguard Worker 3227*cda5da8dSAndroid Build Coastguard Worker if pl == [(0, 0), (0, 0)]: 3228*cda5da8dSAndroid Build Coastguard Worker usepc = "" 3229*cda5da8dSAndroid Build Coastguard Worker else: 3230*cda5da8dSAndroid Build Coastguard Worker usepc = pc 3231*cda5da8dSAndroid Build Coastguard Worker screen._drawline(cLI, pl, fill=usepc, width=ps) 3232*cda5da8dSAndroid Build Coastguard Worker 3233*cda5da8dSAndroid Build Coastguard Worker todelete = [i for i in self.items if (i not in items) and 3234*cda5da8dSAndroid Build Coastguard Worker (screen._type(i) == "line")] 3235*cda5da8dSAndroid Build Coastguard Worker for i in todelete: 3236*cda5da8dSAndroid Build Coastguard Worker screen._delete(i) 3237*cda5da8dSAndroid Build Coastguard Worker self.items.remove(i) 3238*cda5da8dSAndroid Build Coastguard Worker 3239*cda5da8dSAndroid Build Coastguard Worker start = old 3240*cda5da8dSAndroid Build Coastguard Worker if self._speed and screen._tracing == 1: 3241*cda5da8dSAndroid Build Coastguard Worker diff = old - new 3242*cda5da8dSAndroid Build Coastguard Worker diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2 3243*cda5da8dSAndroid Build Coastguard Worker nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed)) 3244*cda5da8dSAndroid Build Coastguard Worker delta = diff * (1.0/nhops) 3245*cda5da8dSAndroid Build Coastguard Worker for n in range(1, nhops): 3246*cda5da8dSAndroid Build Coastguard Worker if n == 1: 3247*cda5da8dSAndroid Build Coastguard Worker top = True 3248*cda5da8dSAndroid Build Coastguard Worker else: 3249*cda5da8dSAndroid Build Coastguard Worker top = False 3250*cda5da8dSAndroid Build Coastguard Worker self._position = new + delta * n 3251*cda5da8dSAndroid Build Coastguard Worker if drawing: 3252*cda5da8dSAndroid Build Coastguard Worker screen._drawline(self.drawingLineItem, 3253*cda5da8dSAndroid Build Coastguard Worker (start, self._position), 3254*cda5da8dSAndroid Build Coastguard Worker pc, ps, top) 3255*cda5da8dSAndroid Build Coastguard Worker self._update() 3256*cda5da8dSAndroid Build Coastguard Worker if drawing: 3257*cda5da8dSAndroid Build Coastguard Worker screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)), 3258*cda5da8dSAndroid Build Coastguard Worker fill="", width=ps) 3259*cda5da8dSAndroid Build Coastguard Worker # Turtle now at position old, 3260*cda5da8dSAndroid Build Coastguard Worker self._position = old 3261*cda5da8dSAndroid Build Coastguard Worker ## if undo is done during creating a polygon, the last vertex 3262*cda5da8dSAndroid Build Coastguard Worker ## will be deleted. if the polygon is entirely deleted, 3263*cda5da8dSAndroid Build Coastguard Worker ## creatingPoly will be set to False. 3264*cda5da8dSAndroid Build Coastguard Worker ## Polygons created before the last one will not be affected by undo() 3265*cda5da8dSAndroid Build Coastguard Worker if self._creatingPoly: 3266*cda5da8dSAndroid Build Coastguard Worker if len(self._poly) > 0: 3267*cda5da8dSAndroid Build Coastguard Worker self._poly.pop() 3268*cda5da8dSAndroid Build Coastguard Worker if self._poly == []: 3269*cda5da8dSAndroid Build Coastguard Worker self._creatingPoly = False 3270*cda5da8dSAndroid Build Coastguard Worker self._poly = None 3271*cda5da8dSAndroid Build Coastguard Worker if filling: 3272*cda5da8dSAndroid Build Coastguard Worker if self._fillpath == []: 3273*cda5da8dSAndroid Build Coastguard Worker self._fillpath = None 3274*cda5da8dSAndroid Build Coastguard Worker print("Unwahrscheinlich in _undogoto!") 3275*cda5da8dSAndroid Build Coastguard Worker elif self._fillpath is not None: 3276*cda5da8dSAndroid Build Coastguard Worker self._fillpath.pop() 3277*cda5da8dSAndroid Build Coastguard Worker self._update() #count=True) 3278*cda5da8dSAndroid Build Coastguard Worker 3279*cda5da8dSAndroid Build Coastguard Worker def _rotate(self, angle): 3280*cda5da8dSAndroid Build Coastguard Worker """Turns pen clockwise by angle. 3281*cda5da8dSAndroid Build Coastguard Worker """ 3282*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer: 3283*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.push(("rot", angle, self._degreesPerAU)) 3284*cda5da8dSAndroid Build Coastguard Worker angle *= self._degreesPerAU 3285*cda5da8dSAndroid Build Coastguard Worker neworient = self._orient.rotate(angle) 3286*cda5da8dSAndroid Build Coastguard Worker tracing = self.screen._tracing 3287*cda5da8dSAndroid Build Coastguard Worker if tracing == 1 and self._speed > 0: 3288*cda5da8dSAndroid Build Coastguard Worker anglevel = 3.0 * self._speed 3289*cda5da8dSAndroid Build Coastguard Worker steps = 1 + int(abs(angle)/anglevel) 3290*cda5da8dSAndroid Build Coastguard Worker delta = 1.0*angle/steps 3291*cda5da8dSAndroid Build Coastguard Worker for _ in range(steps): 3292*cda5da8dSAndroid Build Coastguard Worker self._orient = self._orient.rotate(delta) 3293*cda5da8dSAndroid Build Coastguard Worker self._update() 3294*cda5da8dSAndroid Build Coastguard Worker self._orient = neworient 3295*cda5da8dSAndroid Build Coastguard Worker self._update() 3296*cda5da8dSAndroid Build Coastguard Worker 3297*cda5da8dSAndroid Build Coastguard Worker def _newLine(self, usePos=True): 3298*cda5da8dSAndroid Build Coastguard Worker """Closes current line item and starts a new one. 3299*cda5da8dSAndroid Build Coastguard Worker Remark: if current line became too long, animation 3300*cda5da8dSAndroid Build Coastguard Worker performance (via _drawline) slowed down considerably. 3301*cda5da8dSAndroid Build Coastguard Worker """ 3302*cda5da8dSAndroid Build Coastguard Worker if len(self.currentLine) > 1: 3303*cda5da8dSAndroid Build Coastguard Worker self.screen._drawline(self.currentLineItem, self.currentLine, 3304*cda5da8dSAndroid Build Coastguard Worker self._pencolor, self._pensize) 3305*cda5da8dSAndroid Build Coastguard Worker self.currentLineItem = self.screen._createline() 3306*cda5da8dSAndroid Build Coastguard Worker self.items.append(self.currentLineItem) 3307*cda5da8dSAndroid Build Coastguard Worker else: 3308*cda5da8dSAndroid Build Coastguard Worker self.screen._drawline(self.currentLineItem, top=True) 3309*cda5da8dSAndroid Build Coastguard Worker self.currentLine = [] 3310*cda5da8dSAndroid Build Coastguard Worker if usePos: 3311*cda5da8dSAndroid Build Coastguard Worker self.currentLine = [self._position] 3312*cda5da8dSAndroid Build Coastguard Worker 3313*cda5da8dSAndroid Build Coastguard Worker def filling(self): 3314*cda5da8dSAndroid Build Coastguard Worker """Return fillstate (True if filling, False else). 3315*cda5da8dSAndroid Build Coastguard Worker 3316*cda5da8dSAndroid Build Coastguard Worker No argument. 3317*cda5da8dSAndroid Build Coastguard Worker 3318*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 3319*cda5da8dSAndroid Build Coastguard Worker >>> turtle.begin_fill() 3320*cda5da8dSAndroid Build Coastguard Worker >>> if turtle.filling(): 3321*cda5da8dSAndroid Build Coastguard Worker ... turtle.pensize(5) 3322*cda5da8dSAndroid Build Coastguard Worker ... else: 3323*cda5da8dSAndroid Build Coastguard Worker ... turtle.pensize(3) 3324*cda5da8dSAndroid Build Coastguard Worker """ 3325*cda5da8dSAndroid Build Coastguard Worker return isinstance(self._fillpath, list) 3326*cda5da8dSAndroid Build Coastguard Worker 3327*cda5da8dSAndroid Build Coastguard Worker def begin_fill(self): 3328*cda5da8dSAndroid Build Coastguard Worker """Called just before drawing a shape to be filled. 3329*cda5da8dSAndroid Build Coastguard Worker 3330*cda5da8dSAndroid Build Coastguard Worker No argument. 3331*cda5da8dSAndroid Build Coastguard Worker 3332*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 3333*cda5da8dSAndroid Build Coastguard Worker >>> turtle.color("black", "red") 3334*cda5da8dSAndroid Build Coastguard Worker >>> turtle.begin_fill() 3335*cda5da8dSAndroid Build Coastguard Worker >>> turtle.circle(60) 3336*cda5da8dSAndroid Build Coastguard Worker >>> turtle.end_fill() 3337*cda5da8dSAndroid Build Coastguard Worker """ 3338*cda5da8dSAndroid Build Coastguard Worker if not self.filling(): 3339*cda5da8dSAndroid Build Coastguard Worker self._fillitem = self.screen._createpoly() 3340*cda5da8dSAndroid Build Coastguard Worker self.items.append(self._fillitem) 3341*cda5da8dSAndroid Build Coastguard Worker self._fillpath = [self._position] 3342*cda5da8dSAndroid Build Coastguard Worker self._newLine() 3343*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer: 3344*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.push(("beginfill", self._fillitem)) 3345*cda5da8dSAndroid Build Coastguard Worker self._update() 3346*cda5da8dSAndroid Build Coastguard Worker 3347*cda5da8dSAndroid Build Coastguard Worker 3348*cda5da8dSAndroid Build Coastguard Worker def end_fill(self): 3349*cda5da8dSAndroid Build Coastguard Worker """Fill the shape drawn after the call begin_fill(). 3350*cda5da8dSAndroid Build Coastguard Worker 3351*cda5da8dSAndroid Build Coastguard Worker No argument. 3352*cda5da8dSAndroid Build Coastguard Worker 3353*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 3354*cda5da8dSAndroid Build Coastguard Worker >>> turtle.color("black", "red") 3355*cda5da8dSAndroid Build Coastguard Worker >>> turtle.begin_fill() 3356*cda5da8dSAndroid Build Coastguard Worker >>> turtle.circle(60) 3357*cda5da8dSAndroid Build Coastguard Worker >>> turtle.end_fill() 3358*cda5da8dSAndroid Build Coastguard Worker """ 3359*cda5da8dSAndroid Build Coastguard Worker if self.filling(): 3360*cda5da8dSAndroid Build Coastguard Worker if len(self._fillpath) > 2: 3361*cda5da8dSAndroid Build Coastguard Worker self.screen._drawpoly(self._fillitem, self._fillpath, 3362*cda5da8dSAndroid Build Coastguard Worker fill=self._fillcolor) 3363*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer: 3364*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.push(("dofill", self._fillitem)) 3365*cda5da8dSAndroid Build Coastguard Worker self._fillitem = self._fillpath = None 3366*cda5da8dSAndroid Build Coastguard Worker self._update() 3367*cda5da8dSAndroid Build Coastguard Worker 3368*cda5da8dSAndroid Build Coastguard Worker def dot(self, size=None, *color): 3369*cda5da8dSAndroid Build Coastguard Worker """Draw a dot with diameter size, using color. 3370*cda5da8dSAndroid Build Coastguard Worker 3371*cda5da8dSAndroid Build Coastguard Worker Optional arguments: 3372*cda5da8dSAndroid Build Coastguard Worker size -- an integer >= 1 (if given) 3373*cda5da8dSAndroid Build Coastguard Worker color -- a colorstring or a numeric color tuple 3374*cda5da8dSAndroid Build Coastguard Worker 3375*cda5da8dSAndroid Build Coastguard Worker Draw a circular dot with diameter size, using color. 3376*cda5da8dSAndroid Build Coastguard Worker If size is not given, the maximum of pensize+4 and 2*pensize is used. 3377*cda5da8dSAndroid Build Coastguard Worker 3378*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 3379*cda5da8dSAndroid Build Coastguard Worker >>> turtle.dot() 3380*cda5da8dSAndroid Build Coastguard Worker >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50) 3381*cda5da8dSAndroid Build Coastguard Worker """ 3382*cda5da8dSAndroid Build Coastguard Worker if not color: 3383*cda5da8dSAndroid Build Coastguard Worker if isinstance(size, (str, tuple)): 3384*cda5da8dSAndroid Build Coastguard Worker color = self._colorstr(size) 3385*cda5da8dSAndroid Build Coastguard Worker size = self._pensize + max(self._pensize, 4) 3386*cda5da8dSAndroid Build Coastguard Worker else: 3387*cda5da8dSAndroid Build Coastguard Worker color = self._pencolor 3388*cda5da8dSAndroid Build Coastguard Worker if not size: 3389*cda5da8dSAndroid Build Coastguard Worker size = self._pensize + max(self._pensize, 4) 3390*cda5da8dSAndroid Build Coastguard Worker else: 3391*cda5da8dSAndroid Build Coastguard Worker if size is None: 3392*cda5da8dSAndroid Build Coastguard Worker size = self._pensize + max(self._pensize, 4) 3393*cda5da8dSAndroid Build Coastguard Worker color = self._colorstr(color) 3394*cda5da8dSAndroid Build Coastguard Worker if hasattr(self.screen, "_dot"): 3395*cda5da8dSAndroid Build Coastguard Worker item = self.screen._dot(self._position, size, color) 3396*cda5da8dSAndroid Build Coastguard Worker self.items.append(item) 3397*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer: 3398*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.push(("dot", item)) 3399*cda5da8dSAndroid Build Coastguard Worker else: 3400*cda5da8dSAndroid Build Coastguard Worker pen = self.pen() 3401*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer: 3402*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.push(["seq"]) 3403*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.cumulate = True 3404*cda5da8dSAndroid Build Coastguard Worker try: 3405*cda5da8dSAndroid Build Coastguard Worker if self.resizemode() == 'auto': 3406*cda5da8dSAndroid Build Coastguard Worker self.ht() 3407*cda5da8dSAndroid Build Coastguard Worker self.pendown() 3408*cda5da8dSAndroid Build Coastguard Worker self.pensize(size) 3409*cda5da8dSAndroid Build Coastguard Worker self.pencolor(color) 3410*cda5da8dSAndroid Build Coastguard Worker self.forward(0) 3411*cda5da8dSAndroid Build Coastguard Worker finally: 3412*cda5da8dSAndroid Build Coastguard Worker self.pen(pen) 3413*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer: 3414*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.cumulate = False 3415*cda5da8dSAndroid Build Coastguard Worker 3416*cda5da8dSAndroid Build Coastguard Worker def _write(self, txt, align, font): 3417*cda5da8dSAndroid Build Coastguard Worker """Performs the writing for write() 3418*cda5da8dSAndroid Build Coastguard Worker """ 3419*cda5da8dSAndroid Build Coastguard Worker item, end = self.screen._write(self._position, txt, align, font, 3420*cda5da8dSAndroid Build Coastguard Worker self._pencolor) 3421*cda5da8dSAndroid Build Coastguard Worker self._update() 3422*cda5da8dSAndroid Build Coastguard Worker self.items.append(item) 3423*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer: 3424*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.push(("wri", item)) 3425*cda5da8dSAndroid Build Coastguard Worker return end 3426*cda5da8dSAndroid Build Coastguard Worker 3427*cda5da8dSAndroid Build Coastguard Worker def write(self, arg, move=False, align="left", font=("Arial", 8, "normal")): 3428*cda5da8dSAndroid Build Coastguard Worker """Write text at the current turtle position. 3429*cda5da8dSAndroid Build Coastguard Worker 3430*cda5da8dSAndroid Build Coastguard Worker Arguments: 3431*cda5da8dSAndroid Build Coastguard Worker arg -- info, which is to be written to the TurtleScreen 3432*cda5da8dSAndroid Build Coastguard Worker move (optional) -- True/False 3433*cda5da8dSAndroid Build Coastguard Worker align (optional) -- one of the strings "left", "center" or right" 3434*cda5da8dSAndroid Build Coastguard Worker font (optional) -- a triple (fontname, fontsize, fonttype) 3435*cda5da8dSAndroid Build Coastguard Worker 3436*cda5da8dSAndroid Build Coastguard Worker Write text - the string representation of arg - at the current 3437*cda5da8dSAndroid Build Coastguard Worker turtle position according to align ("left", "center" or right") 3438*cda5da8dSAndroid Build Coastguard Worker and with the given font. 3439*cda5da8dSAndroid Build Coastguard Worker If move is True, the pen is moved to the bottom-right corner 3440*cda5da8dSAndroid Build Coastguard Worker of the text. By default, move is False. 3441*cda5da8dSAndroid Build Coastguard Worker 3442*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 3443*cda5da8dSAndroid Build Coastguard Worker >>> turtle.write('Home = ', True, align="center") 3444*cda5da8dSAndroid Build Coastguard Worker >>> turtle.write((0,0), True) 3445*cda5da8dSAndroid Build Coastguard Worker """ 3446*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer: 3447*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.push(["seq"]) 3448*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.cumulate = True 3449*cda5da8dSAndroid Build Coastguard Worker end = self._write(str(arg), align.lower(), font) 3450*cda5da8dSAndroid Build Coastguard Worker if move: 3451*cda5da8dSAndroid Build Coastguard Worker x, y = self.pos() 3452*cda5da8dSAndroid Build Coastguard Worker self.setpos(end, y) 3453*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer: 3454*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.cumulate = False 3455*cda5da8dSAndroid Build Coastguard Worker 3456*cda5da8dSAndroid Build Coastguard Worker def begin_poly(self): 3457*cda5da8dSAndroid Build Coastguard Worker """Start recording the vertices of a polygon. 3458*cda5da8dSAndroid Build Coastguard Worker 3459*cda5da8dSAndroid Build Coastguard Worker No argument. 3460*cda5da8dSAndroid Build Coastguard Worker 3461*cda5da8dSAndroid Build Coastguard Worker Start recording the vertices of a polygon. Current turtle position 3462*cda5da8dSAndroid Build Coastguard Worker is first point of polygon. 3463*cda5da8dSAndroid Build Coastguard Worker 3464*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 3465*cda5da8dSAndroid Build Coastguard Worker >>> turtle.begin_poly() 3466*cda5da8dSAndroid Build Coastguard Worker """ 3467*cda5da8dSAndroid Build Coastguard Worker self._poly = [self._position] 3468*cda5da8dSAndroid Build Coastguard Worker self._creatingPoly = True 3469*cda5da8dSAndroid Build Coastguard Worker 3470*cda5da8dSAndroid Build Coastguard Worker def end_poly(self): 3471*cda5da8dSAndroid Build Coastguard Worker """Stop recording the vertices of a polygon. 3472*cda5da8dSAndroid Build Coastguard Worker 3473*cda5da8dSAndroid Build Coastguard Worker No argument. 3474*cda5da8dSAndroid Build Coastguard Worker 3475*cda5da8dSAndroid Build Coastguard Worker Stop recording the vertices of a polygon. Current turtle position is 3476*cda5da8dSAndroid Build Coastguard Worker last point of polygon. This will be connected with the first point. 3477*cda5da8dSAndroid Build Coastguard Worker 3478*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 3479*cda5da8dSAndroid Build Coastguard Worker >>> turtle.end_poly() 3480*cda5da8dSAndroid Build Coastguard Worker """ 3481*cda5da8dSAndroid Build Coastguard Worker self._creatingPoly = False 3482*cda5da8dSAndroid Build Coastguard Worker 3483*cda5da8dSAndroid Build Coastguard Worker def get_poly(self): 3484*cda5da8dSAndroid Build Coastguard Worker """Return the lastly recorded polygon. 3485*cda5da8dSAndroid Build Coastguard Worker 3486*cda5da8dSAndroid Build Coastguard Worker No argument. 3487*cda5da8dSAndroid Build Coastguard Worker 3488*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 3489*cda5da8dSAndroid Build Coastguard Worker >>> p = turtle.get_poly() 3490*cda5da8dSAndroid Build Coastguard Worker >>> turtle.register_shape("myFavouriteShape", p) 3491*cda5da8dSAndroid Build Coastguard Worker """ 3492*cda5da8dSAndroid Build Coastguard Worker ## check if there is any poly? 3493*cda5da8dSAndroid Build Coastguard Worker if self._poly is not None: 3494*cda5da8dSAndroid Build Coastguard Worker return tuple(self._poly) 3495*cda5da8dSAndroid Build Coastguard Worker 3496*cda5da8dSAndroid Build Coastguard Worker def getscreen(self): 3497*cda5da8dSAndroid Build Coastguard Worker """Return the TurtleScreen object, the turtle is drawing on. 3498*cda5da8dSAndroid Build Coastguard Worker 3499*cda5da8dSAndroid Build Coastguard Worker No argument. 3500*cda5da8dSAndroid Build Coastguard Worker 3501*cda5da8dSAndroid Build Coastguard Worker Return the TurtleScreen object, the turtle is drawing on. 3502*cda5da8dSAndroid Build Coastguard Worker So TurtleScreen-methods can be called for that object. 3503*cda5da8dSAndroid Build Coastguard Worker 3504*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 3505*cda5da8dSAndroid Build Coastguard Worker >>> ts = turtle.getscreen() 3506*cda5da8dSAndroid Build Coastguard Worker >>> ts 3507*cda5da8dSAndroid Build Coastguard Worker <turtle.TurtleScreen object at 0x0106B770> 3508*cda5da8dSAndroid Build Coastguard Worker >>> ts.bgcolor("pink") 3509*cda5da8dSAndroid Build Coastguard Worker """ 3510*cda5da8dSAndroid Build Coastguard Worker return self.screen 3511*cda5da8dSAndroid Build Coastguard Worker 3512*cda5da8dSAndroid Build Coastguard Worker def getturtle(self): 3513*cda5da8dSAndroid Build Coastguard Worker """Return the Turtleobject itself. 3514*cda5da8dSAndroid Build Coastguard Worker 3515*cda5da8dSAndroid Build Coastguard Worker No argument. 3516*cda5da8dSAndroid Build Coastguard Worker 3517*cda5da8dSAndroid Build Coastguard Worker Only reasonable use: as a function to return the 'anonymous turtle': 3518*cda5da8dSAndroid Build Coastguard Worker 3519*cda5da8dSAndroid Build Coastguard Worker Example: 3520*cda5da8dSAndroid Build Coastguard Worker >>> pet = getturtle() 3521*cda5da8dSAndroid Build Coastguard Worker >>> pet.fd(50) 3522*cda5da8dSAndroid Build Coastguard Worker >>> pet 3523*cda5da8dSAndroid Build Coastguard Worker <turtle.Turtle object at 0x0187D810> 3524*cda5da8dSAndroid Build Coastguard Worker >>> turtles() 3525*cda5da8dSAndroid Build Coastguard Worker [<turtle.Turtle object at 0x0187D810>] 3526*cda5da8dSAndroid Build Coastguard Worker """ 3527*cda5da8dSAndroid Build Coastguard Worker return self 3528*cda5da8dSAndroid Build Coastguard Worker 3529*cda5da8dSAndroid Build Coastguard Worker getpen = getturtle 3530*cda5da8dSAndroid Build Coastguard Worker 3531*cda5da8dSAndroid Build Coastguard Worker 3532*cda5da8dSAndroid Build Coastguard Worker ################################################################ 3533*cda5da8dSAndroid Build Coastguard Worker ### screen oriented methods recurring to methods of TurtleScreen 3534*cda5da8dSAndroid Build Coastguard Worker ################################################################ 3535*cda5da8dSAndroid Build Coastguard Worker 3536*cda5da8dSAndroid Build Coastguard Worker def _delay(self, delay=None): 3537*cda5da8dSAndroid Build Coastguard Worker """Set delay value which determines speed of turtle animation. 3538*cda5da8dSAndroid Build Coastguard Worker """ 3539*cda5da8dSAndroid Build Coastguard Worker return self.screen.delay(delay) 3540*cda5da8dSAndroid Build Coastguard Worker 3541*cda5da8dSAndroid Build Coastguard Worker def onclick(self, fun, btn=1, add=None): 3542*cda5da8dSAndroid Build Coastguard Worker """Bind fun to mouse-click event on this turtle on canvas. 3543*cda5da8dSAndroid Build Coastguard Worker 3544*cda5da8dSAndroid Build Coastguard Worker Arguments: 3545*cda5da8dSAndroid Build Coastguard Worker fun -- a function with two arguments, to which will be assigned 3546*cda5da8dSAndroid Build Coastguard Worker the coordinates of the clicked point on the canvas. 3547*cda5da8dSAndroid Build Coastguard Worker btn -- number of the mouse-button defaults to 1 (left mouse button). 3548*cda5da8dSAndroid Build Coastguard Worker add -- True or False. If True, new binding will be added, otherwise 3549*cda5da8dSAndroid Build Coastguard Worker it will replace a former binding. 3550*cda5da8dSAndroid Build Coastguard Worker 3551*cda5da8dSAndroid Build Coastguard Worker Example for the anonymous turtle, i. e. the procedural way: 3552*cda5da8dSAndroid Build Coastguard Worker 3553*cda5da8dSAndroid Build Coastguard Worker >>> def turn(x, y): 3554*cda5da8dSAndroid Build Coastguard Worker ... left(360) 3555*cda5da8dSAndroid Build Coastguard Worker ... 3556*cda5da8dSAndroid Build Coastguard Worker >>> onclick(turn) # Now clicking into the turtle will turn it. 3557*cda5da8dSAndroid Build Coastguard Worker >>> onclick(None) # event-binding will be removed 3558*cda5da8dSAndroid Build Coastguard Worker """ 3559*cda5da8dSAndroid Build Coastguard Worker self.screen._onclick(self.turtle._item, fun, btn, add) 3560*cda5da8dSAndroid Build Coastguard Worker self._update() 3561*cda5da8dSAndroid Build Coastguard Worker 3562*cda5da8dSAndroid Build Coastguard Worker def onrelease(self, fun, btn=1, add=None): 3563*cda5da8dSAndroid Build Coastguard Worker """Bind fun to mouse-button-release event on this turtle on canvas. 3564*cda5da8dSAndroid Build Coastguard Worker 3565*cda5da8dSAndroid Build Coastguard Worker Arguments: 3566*cda5da8dSAndroid Build Coastguard Worker fun -- a function with two arguments, to which will be assigned 3567*cda5da8dSAndroid Build Coastguard Worker the coordinates of the clicked point on the canvas. 3568*cda5da8dSAndroid Build Coastguard Worker btn -- number of the mouse-button defaults to 1 (left mouse button). 3569*cda5da8dSAndroid Build Coastguard Worker 3570*cda5da8dSAndroid Build Coastguard Worker Example (for a MyTurtle instance named joe): 3571*cda5da8dSAndroid Build Coastguard Worker >>> class MyTurtle(Turtle): 3572*cda5da8dSAndroid Build Coastguard Worker ... def glow(self,x,y): 3573*cda5da8dSAndroid Build Coastguard Worker ... self.fillcolor("red") 3574*cda5da8dSAndroid Build Coastguard Worker ... def unglow(self,x,y): 3575*cda5da8dSAndroid Build Coastguard Worker ... self.fillcolor("") 3576*cda5da8dSAndroid Build Coastguard Worker ... 3577*cda5da8dSAndroid Build Coastguard Worker >>> joe = MyTurtle() 3578*cda5da8dSAndroid Build Coastguard Worker >>> joe.onclick(joe.glow) 3579*cda5da8dSAndroid Build Coastguard Worker >>> joe.onrelease(joe.unglow) 3580*cda5da8dSAndroid Build Coastguard Worker 3581*cda5da8dSAndroid Build Coastguard Worker Clicking on joe turns fillcolor red, unclicking turns it to 3582*cda5da8dSAndroid Build Coastguard Worker transparent. 3583*cda5da8dSAndroid Build Coastguard Worker """ 3584*cda5da8dSAndroid Build Coastguard Worker self.screen._onrelease(self.turtle._item, fun, btn, add) 3585*cda5da8dSAndroid Build Coastguard Worker self._update() 3586*cda5da8dSAndroid Build Coastguard Worker 3587*cda5da8dSAndroid Build Coastguard Worker def ondrag(self, fun, btn=1, add=None): 3588*cda5da8dSAndroid Build Coastguard Worker """Bind fun to mouse-move event on this turtle on canvas. 3589*cda5da8dSAndroid Build Coastguard Worker 3590*cda5da8dSAndroid Build Coastguard Worker Arguments: 3591*cda5da8dSAndroid Build Coastguard Worker fun -- a function with two arguments, to which will be assigned 3592*cda5da8dSAndroid Build Coastguard Worker the coordinates of the clicked point on the canvas. 3593*cda5da8dSAndroid Build Coastguard Worker btn -- number of the mouse-button defaults to 1 (left mouse button). 3594*cda5da8dSAndroid Build Coastguard Worker 3595*cda5da8dSAndroid Build Coastguard Worker Every sequence of mouse-move-events on a turtle is preceded by a 3596*cda5da8dSAndroid Build Coastguard Worker mouse-click event on that turtle. 3597*cda5da8dSAndroid Build Coastguard Worker 3598*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 3599*cda5da8dSAndroid Build Coastguard Worker >>> turtle.ondrag(turtle.goto) 3600*cda5da8dSAndroid Build Coastguard Worker 3601*cda5da8dSAndroid Build Coastguard Worker Subsequently clicking and dragging a Turtle will move it 3602*cda5da8dSAndroid Build Coastguard Worker across the screen thereby producing handdrawings (if pen is 3603*cda5da8dSAndroid Build Coastguard Worker down). 3604*cda5da8dSAndroid Build Coastguard Worker """ 3605*cda5da8dSAndroid Build Coastguard Worker self.screen._ondrag(self.turtle._item, fun, btn, add) 3606*cda5da8dSAndroid Build Coastguard Worker 3607*cda5da8dSAndroid Build Coastguard Worker 3608*cda5da8dSAndroid Build Coastguard Worker def _undo(self, action, data): 3609*cda5da8dSAndroid Build Coastguard Worker """Does the main part of the work for undo() 3610*cda5da8dSAndroid Build Coastguard Worker """ 3611*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer is None: 3612*cda5da8dSAndroid Build Coastguard Worker return 3613*cda5da8dSAndroid Build Coastguard Worker if action == "rot": 3614*cda5da8dSAndroid Build Coastguard Worker angle, degPAU = data 3615*cda5da8dSAndroid Build Coastguard Worker self._rotate(-angle*degPAU/self._degreesPerAU) 3616*cda5da8dSAndroid Build Coastguard Worker dummy = self.undobuffer.pop() 3617*cda5da8dSAndroid Build Coastguard Worker elif action == "stamp": 3618*cda5da8dSAndroid Build Coastguard Worker stitem = data[0] 3619*cda5da8dSAndroid Build Coastguard Worker self.clearstamp(stitem) 3620*cda5da8dSAndroid Build Coastguard Worker elif action == "go": 3621*cda5da8dSAndroid Build Coastguard Worker self._undogoto(data) 3622*cda5da8dSAndroid Build Coastguard Worker elif action in ["wri", "dot"]: 3623*cda5da8dSAndroid Build Coastguard Worker item = data[0] 3624*cda5da8dSAndroid Build Coastguard Worker self.screen._delete(item) 3625*cda5da8dSAndroid Build Coastguard Worker self.items.remove(item) 3626*cda5da8dSAndroid Build Coastguard Worker elif action == "dofill": 3627*cda5da8dSAndroid Build Coastguard Worker item = data[0] 3628*cda5da8dSAndroid Build Coastguard Worker self.screen._drawpoly(item, ((0, 0),(0, 0),(0, 0)), 3629*cda5da8dSAndroid Build Coastguard Worker fill="", outline="") 3630*cda5da8dSAndroid Build Coastguard Worker elif action == "beginfill": 3631*cda5da8dSAndroid Build Coastguard Worker item = data[0] 3632*cda5da8dSAndroid Build Coastguard Worker self._fillitem = self._fillpath = None 3633*cda5da8dSAndroid Build Coastguard Worker if item in self.items: 3634*cda5da8dSAndroid Build Coastguard Worker self.screen._delete(item) 3635*cda5da8dSAndroid Build Coastguard Worker self.items.remove(item) 3636*cda5da8dSAndroid Build Coastguard Worker elif action == "pen": 3637*cda5da8dSAndroid Build Coastguard Worker TPen.pen(self, data[0]) 3638*cda5da8dSAndroid Build Coastguard Worker self.undobuffer.pop() 3639*cda5da8dSAndroid Build Coastguard Worker 3640*cda5da8dSAndroid Build Coastguard Worker def undo(self): 3641*cda5da8dSAndroid Build Coastguard Worker """undo (repeatedly) the last turtle action. 3642*cda5da8dSAndroid Build Coastguard Worker 3643*cda5da8dSAndroid Build Coastguard Worker No argument. 3644*cda5da8dSAndroid Build Coastguard Worker 3645*cda5da8dSAndroid Build Coastguard Worker undo (repeatedly) the last turtle action. 3646*cda5da8dSAndroid Build Coastguard Worker Number of available undo actions is determined by the size of 3647*cda5da8dSAndroid Build Coastguard Worker the undobuffer. 3648*cda5da8dSAndroid Build Coastguard Worker 3649*cda5da8dSAndroid Build Coastguard Worker Example (for a Turtle instance named turtle): 3650*cda5da8dSAndroid Build Coastguard Worker >>> for i in range(4): 3651*cda5da8dSAndroid Build Coastguard Worker ... turtle.fd(50); turtle.lt(80) 3652*cda5da8dSAndroid Build Coastguard Worker ... 3653*cda5da8dSAndroid Build Coastguard Worker >>> for i in range(8): 3654*cda5da8dSAndroid Build Coastguard Worker ... turtle.undo() 3655*cda5da8dSAndroid Build Coastguard Worker ... 3656*cda5da8dSAndroid Build Coastguard Worker """ 3657*cda5da8dSAndroid Build Coastguard Worker if self.undobuffer is None: 3658*cda5da8dSAndroid Build Coastguard Worker return 3659*cda5da8dSAndroid Build Coastguard Worker item = self.undobuffer.pop() 3660*cda5da8dSAndroid Build Coastguard Worker action = item[0] 3661*cda5da8dSAndroid Build Coastguard Worker data = item[1:] 3662*cda5da8dSAndroid Build Coastguard Worker if action == "seq": 3663*cda5da8dSAndroid Build Coastguard Worker while data: 3664*cda5da8dSAndroid Build Coastguard Worker item = data.pop() 3665*cda5da8dSAndroid Build Coastguard Worker self._undo(item[0], item[1:]) 3666*cda5da8dSAndroid Build Coastguard Worker else: 3667*cda5da8dSAndroid Build Coastguard Worker self._undo(action, data) 3668*cda5da8dSAndroid Build Coastguard Worker 3669*cda5da8dSAndroid Build Coastguard Worker turtlesize = shapesize 3670*cda5da8dSAndroid Build Coastguard Worker 3671*cda5da8dSAndroid Build Coastguard WorkerRawPen = RawTurtle 3672*cda5da8dSAndroid Build Coastguard Worker 3673*cda5da8dSAndroid Build Coastguard Worker### Screen - Singleton ######################## 3674*cda5da8dSAndroid Build Coastguard Worker 3675*cda5da8dSAndroid Build Coastguard Workerdef Screen(): 3676*cda5da8dSAndroid Build Coastguard Worker """Return the singleton screen object. 3677*cda5da8dSAndroid Build Coastguard Worker If none exists at the moment, create a new one and return it, 3678*cda5da8dSAndroid Build Coastguard Worker else return the existing one.""" 3679*cda5da8dSAndroid Build Coastguard Worker if Turtle._screen is None: 3680*cda5da8dSAndroid Build Coastguard Worker Turtle._screen = _Screen() 3681*cda5da8dSAndroid Build Coastguard Worker return Turtle._screen 3682*cda5da8dSAndroid Build Coastguard Worker 3683*cda5da8dSAndroid Build Coastguard Workerclass _Screen(TurtleScreen): 3684*cda5da8dSAndroid Build Coastguard Worker 3685*cda5da8dSAndroid Build Coastguard Worker _root = None 3686*cda5da8dSAndroid Build Coastguard Worker _canvas = None 3687*cda5da8dSAndroid Build Coastguard Worker _title = _CFG["title"] 3688*cda5da8dSAndroid Build Coastguard Worker 3689*cda5da8dSAndroid Build Coastguard Worker def __init__(self): 3690*cda5da8dSAndroid Build Coastguard Worker # XXX there is no need for this code to be conditional, 3691*cda5da8dSAndroid Build Coastguard Worker # as there will be only a single _Screen instance, anyway 3692*cda5da8dSAndroid Build Coastguard Worker # XXX actually, the turtle demo is injecting root window, 3693*cda5da8dSAndroid Build Coastguard Worker # so perhaps the conditional creation of a root should be 3694*cda5da8dSAndroid Build Coastguard Worker # preserved (perhaps by passing it as an optional parameter) 3695*cda5da8dSAndroid Build Coastguard Worker if _Screen._root is None: 3696*cda5da8dSAndroid Build Coastguard Worker _Screen._root = self._root = _Root() 3697*cda5da8dSAndroid Build Coastguard Worker self._root.title(_Screen._title) 3698*cda5da8dSAndroid Build Coastguard Worker self._root.ondestroy(self._destroy) 3699*cda5da8dSAndroid Build Coastguard Worker if _Screen._canvas is None: 3700*cda5da8dSAndroid Build Coastguard Worker width = _CFG["width"] 3701*cda5da8dSAndroid Build Coastguard Worker height = _CFG["height"] 3702*cda5da8dSAndroid Build Coastguard Worker canvwidth = _CFG["canvwidth"] 3703*cda5da8dSAndroid Build Coastguard Worker canvheight = _CFG["canvheight"] 3704*cda5da8dSAndroid Build Coastguard Worker leftright = _CFG["leftright"] 3705*cda5da8dSAndroid Build Coastguard Worker topbottom = _CFG["topbottom"] 3706*cda5da8dSAndroid Build Coastguard Worker self._root.setupcanvas(width, height, canvwidth, canvheight) 3707*cda5da8dSAndroid Build Coastguard Worker _Screen._canvas = self._root._getcanvas() 3708*cda5da8dSAndroid Build Coastguard Worker TurtleScreen.__init__(self, _Screen._canvas) 3709*cda5da8dSAndroid Build Coastguard Worker self.setup(width, height, leftright, topbottom) 3710*cda5da8dSAndroid Build Coastguard Worker 3711*cda5da8dSAndroid Build Coastguard Worker def setup(self, width=_CFG["width"], height=_CFG["height"], 3712*cda5da8dSAndroid Build Coastguard Worker startx=_CFG["leftright"], starty=_CFG["topbottom"]): 3713*cda5da8dSAndroid Build Coastguard Worker """ Set the size and position of the main window. 3714*cda5da8dSAndroid Build Coastguard Worker 3715*cda5da8dSAndroid Build Coastguard Worker Arguments: 3716*cda5da8dSAndroid Build Coastguard Worker width: as integer a size in pixels, as float a fraction of the screen. 3717*cda5da8dSAndroid Build Coastguard Worker Default is 50% of screen. 3718*cda5da8dSAndroid Build Coastguard Worker height: as integer the height in pixels, as float a fraction of the 3719*cda5da8dSAndroid Build Coastguard Worker screen. Default is 75% of screen. 3720*cda5da8dSAndroid Build Coastguard Worker startx: if positive, starting position in pixels from the left 3721*cda5da8dSAndroid Build Coastguard Worker edge of the screen, if negative from the right edge 3722*cda5da8dSAndroid Build Coastguard Worker Default, startx=None is to center window horizontally. 3723*cda5da8dSAndroid Build Coastguard Worker starty: if positive, starting position in pixels from the top 3724*cda5da8dSAndroid Build Coastguard Worker edge of the screen, if negative from the bottom edge 3725*cda5da8dSAndroid Build Coastguard Worker Default, starty=None is to center window vertically. 3726*cda5da8dSAndroid Build Coastguard Worker 3727*cda5da8dSAndroid Build Coastguard Worker Examples (for a Screen instance named screen): 3728*cda5da8dSAndroid Build Coastguard Worker >>> screen.setup (width=200, height=200, startx=0, starty=0) 3729*cda5da8dSAndroid Build Coastguard Worker 3730*cda5da8dSAndroid Build Coastguard Worker sets window to 200x200 pixels, in upper left of screen 3731*cda5da8dSAndroid Build Coastguard Worker 3732*cda5da8dSAndroid Build Coastguard Worker >>> screen.setup(width=.75, height=0.5, startx=None, starty=None) 3733*cda5da8dSAndroid Build Coastguard Worker 3734*cda5da8dSAndroid Build Coastguard Worker sets window to 75% of screen by 50% of screen and centers 3735*cda5da8dSAndroid Build Coastguard Worker """ 3736*cda5da8dSAndroid Build Coastguard Worker if not hasattr(self._root, "set_geometry"): 3737*cda5da8dSAndroid Build Coastguard Worker return 3738*cda5da8dSAndroid Build Coastguard Worker sw = self._root.win_width() 3739*cda5da8dSAndroid Build Coastguard Worker sh = self._root.win_height() 3740*cda5da8dSAndroid Build Coastguard Worker if isinstance(width, float) and 0 <= width <= 1: 3741*cda5da8dSAndroid Build Coastguard Worker width = sw*width 3742*cda5da8dSAndroid Build Coastguard Worker if startx is None: 3743*cda5da8dSAndroid Build Coastguard Worker startx = (sw - width) / 2 3744*cda5da8dSAndroid Build Coastguard Worker if isinstance(height, float) and 0 <= height <= 1: 3745*cda5da8dSAndroid Build Coastguard Worker height = sh*height 3746*cda5da8dSAndroid Build Coastguard Worker if starty is None: 3747*cda5da8dSAndroid Build Coastguard Worker starty = (sh - height) / 2 3748*cda5da8dSAndroid Build Coastguard Worker self._root.set_geometry(width, height, startx, starty) 3749*cda5da8dSAndroid Build Coastguard Worker self.update() 3750*cda5da8dSAndroid Build Coastguard Worker 3751*cda5da8dSAndroid Build Coastguard Worker def title(self, titlestring): 3752*cda5da8dSAndroid Build Coastguard Worker """Set title of turtle-window 3753*cda5da8dSAndroid Build Coastguard Worker 3754*cda5da8dSAndroid Build Coastguard Worker Argument: 3755*cda5da8dSAndroid Build Coastguard Worker titlestring -- a string, to appear in the titlebar of the 3756*cda5da8dSAndroid Build Coastguard Worker turtle graphics window. 3757*cda5da8dSAndroid Build Coastguard Worker 3758*cda5da8dSAndroid Build Coastguard Worker This is a method of Screen-class. Not available for TurtleScreen- 3759*cda5da8dSAndroid Build Coastguard Worker objects. 3760*cda5da8dSAndroid Build Coastguard Worker 3761*cda5da8dSAndroid Build Coastguard Worker Example (for a Screen instance named screen): 3762*cda5da8dSAndroid Build Coastguard Worker >>> screen.title("Welcome to the turtle-zoo!") 3763*cda5da8dSAndroid Build Coastguard Worker """ 3764*cda5da8dSAndroid Build Coastguard Worker if _Screen._root is not None: 3765*cda5da8dSAndroid Build Coastguard Worker _Screen._root.title(titlestring) 3766*cda5da8dSAndroid Build Coastguard Worker _Screen._title = titlestring 3767*cda5da8dSAndroid Build Coastguard Worker 3768*cda5da8dSAndroid Build Coastguard Worker def _destroy(self): 3769*cda5da8dSAndroid Build Coastguard Worker root = self._root 3770*cda5da8dSAndroid Build Coastguard Worker if root is _Screen._root: 3771*cda5da8dSAndroid Build Coastguard Worker Turtle._pen = None 3772*cda5da8dSAndroid Build Coastguard Worker Turtle._screen = None 3773*cda5da8dSAndroid Build Coastguard Worker _Screen._root = None 3774*cda5da8dSAndroid Build Coastguard Worker _Screen._canvas = None 3775*cda5da8dSAndroid Build Coastguard Worker TurtleScreen._RUNNING = False 3776*cda5da8dSAndroid Build Coastguard Worker root.destroy() 3777*cda5da8dSAndroid Build Coastguard Worker 3778*cda5da8dSAndroid Build Coastguard Worker def bye(self): 3779*cda5da8dSAndroid Build Coastguard Worker """Shut the turtlegraphics window. 3780*cda5da8dSAndroid Build Coastguard Worker 3781*cda5da8dSAndroid Build Coastguard Worker Example (for a TurtleScreen instance named screen): 3782*cda5da8dSAndroid Build Coastguard Worker >>> screen.bye() 3783*cda5da8dSAndroid Build Coastguard Worker """ 3784*cda5da8dSAndroid Build Coastguard Worker self._destroy() 3785*cda5da8dSAndroid Build Coastguard Worker 3786*cda5da8dSAndroid Build Coastguard Worker def exitonclick(self): 3787*cda5da8dSAndroid Build Coastguard Worker """Go into mainloop until the mouse is clicked. 3788*cda5da8dSAndroid Build Coastguard Worker 3789*cda5da8dSAndroid Build Coastguard Worker No arguments. 3790*cda5da8dSAndroid Build Coastguard Worker 3791*cda5da8dSAndroid Build Coastguard Worker Bind bye() method to mouseclick on TurtleScreen. 3792*cda5da8dSAndroid Build Coastguard Worker If "using_IDLE" - value in configuration dictionary is False 3793*cda5da8dSAndroid Build Coastguard Worker (default value), enter mainloop. 3794*cda5da8dSAndroid Build Coastguard Worker If IDLE with -n switch (no subprocess) is used, this value should be 3795*cda5da8dSAndroid Build Coastguard Worker set to True in turtle.cfg. In this case IDLE's mainloop 3796*cda5da8dSAndroid Build Coastguard Worker is active also for the client script. 3797*cda5da8dSAndroid Build Coastguard Worker 3798*cda5da8dSAndroid Build Coastguard Worker This is a method of the Screen-class and not available for 3799*cda5da8dSAndroid Build Coastguard Worker TurtleScreen instances. 3800*cda5da8dSAndroid Build Coastguard Worker 3801*cda5da8dSAndroid Build Coastguard Worker Example (for a Screen instance named screen): 3802*cda5da8dSAndroid Build Coastguard Worker >>> screen.exitonclick() 3803*cda5da8dSAndroid Build Coastguard Worker 3804*cda5da8dSAndroid Build Coastguard Worker """ 3805*cda5da8dSAndroid Build Coastguard Worker def exitGracefully(x, y): 3806*cda5da8dSAndroid Build Coastguard Worker """Screen.bye() with two dummy-parameters""" 3807*cda5da8dSAndroid Build Coastguard Worker self.bye() 3808*cda5da8dSAndroid Build Coastguard Worker self.onclick(exitGracefully) 3809*cda5da8dSAndroid Build Coastguard Worker if _CFG["using_IDLE"]: 3810*cda5da8dSAndroid Build Coastguard Worker return 3811*cda5da8dSAndroid Build Coastguard Worker try: 3812*cda5da8dSAndroid Build Coastguard Worker mainloop() 3813*cda5da8dSAndroid Build Coastguard Worker except AttributeError: 3814*cda5da8dSAndroid Build Coastguard Worker exit(0) 3815*cda5da8dSAndroid Build Coastguard Worker 3816*cda5da8dSAndroid Build Coastguard Workerclass Turtle(RawTurtle): 3817*cda5da8dSAndroid Build Coastguard Worker """RawTurtle auto-creating (scrolled) canvas. 3818*cda5da8dSAndroid Build Coastguard Worker 3819*cda5da8dSAndroid Build Coastguard Worker When a Turtle object is created or a function derived from some 3820*cda5da8dSAndroid Build Coastguard Worker Turtle method is called a TurtleScreen object is automatically created. 3821*cda5da8dSAndroid Build Coastguard Worker """ 3822*cda5da8dSAndroid Build Coastguard Worker _pen = None 3823*cda5da8dSAndroid Build Coastguard Worker _screen = None 3824*cda5da8dSAndroid Build Coastguard Worker 3825*cda5da8dSAndroid Build Coastguard Worker def __init__(self, 3826*cda5da8dSAndroid Build Coastguard Worker shape=_CFG["shape"], 3827*cda5da8dSAndroid Build Coastguard Worker undobuffersize=_CFG["undobuffersize"], 3828*cda5da8dSAndroid Build Coastguard Worker visible=_CFG["visible"]): 3829*cda5da8dSAndroid Build Coastguard Worker if Turtle._screen is None: 3830*cda5da8dSAndroid Build Coastguard Worker Turtle._screen = Screen() 3831*cda5da8dSAndroid Build Coastguard Worker RawTurtle.__init__(self, Turtle._screen, 3832*cda5da8dSAndroid Build Coastguard Worker shape=shape, 3833*cda5da8dSAndroid Build Coastguard Worker undobuffersize=undobuffersize, 3834*cda5da8dSAndroid Build Coastguard Worker visible=visible) 3835*cda5da8dSAndroid Build Coastguard Worker 3836*cda5da8dSAndroid Build Coastguard WorkerPen = Turtle 3837*cda5da8dSAndroid Build Coastguard Worker 3838*cda5da8dSAndroid Build Coastguard Workerdef write_docstringdict(filename="turtle_docstringdict"): 3839*cda5da8dSAndroid Build Coastguard Worker """Create and write docstring-dictionary to file. 3840*cda5da8dSAndroid Build Coastguard Worker 3841*cda5da8dSAndroid Build Coastguard Worker Optional argument: 3842*cda5da8dSAndroid Build Coastguard Worker filename -- a string, used as filename 3843*cda5da8dSAndroid Build Coastguard Worker default value is turtle_docstringdict 3844*cda5da8dSAndroid Build Coastguard Worker 3845*cda5da8dSAndroid Build Coastguard Worker Has to be called explicitly, (not used by the turtle-graphics classes) 3846*cda5da8dSAndroid Build Coastguard Worker The docstring dictionary will be written to the Python script <filename>.py 3847*cda5da8dSAndroid Build Coastguard Worker It is intended to serve as a template for translation of the docstrings 3848*cda5da8dSAndroid Build Coastguard Worker into different languages. 3849*cda5da8dSAndroid Build Coastguard Worker """ 3850*cda5da8dSAndroid Build Coastguard Worker docsdict = {} 3851*cda5da8dSAndroid Build Coastguard Worker 3852*cda5da8dSAndroid Build Coastguard Worker for methodname in _tg_screen_functions: 3853*cda5da8dSAndroid Build Coastguard Worker key = "_Screen."+methodname 3854*cda5da8dSAndroid Build Coastguard Worker docsdict[key] = eval(key).__doc__ 3855*cda5da8dSAndroid Build Coastguard Worker for methodname in _tg_turtle_functions: 3856*cda5da8dSAndroid Build Coastguard Worker key = "Turtle."+methodname 3857*cda5da8dSAndroid Build Coastguard Worker docsdict[key] = eval(key).__doc__ 3858*cda5da8dSAndroid Build Coastguard Worker 3859*cda5da8dSAndroid Build Coastguard Worker with open("%s.py" % filename,"w") as f: 3860*cda5da8dSAndroid Build Coastguard Worker keys = sorted(x for x in docsdict 3861*cda5da8dSAndroid Build Coastguard Worker if x.split('.')[1] not in _alias_list) 3862*cda5da8dSAndroid Build Coastguard Worker f.write('docsdict = {\n\n') 3863*cda5da8dSAndroid Build Coastguard Worker for key in keys[:-1]: 3864*cda5da8dSAndroid Build Coastguard Worker f.write('%s :\n' % repr(key)) 3865*cda5da8dSAndroid Build Coastguard Worker f.write(' """%s\n""",\n\n' % docsdict[key]) 3866*cda5da8dSAndroid Build Coastguard Worker key = keys[-1] 3867*cda5da8dSAndroid Build Coastguard Worker f.write('%s :\n' % repr(key)) 3868*cda5da8dSAndroid Build Coastguard Worker f.write(' """%s\n"""\n\n' % docsdict[key]) 3869*cda5da8dSAndroid Build Coastguard Worker f.write("}\n") 3870*cda5da8dSAndroid Build Coastguard Worker f.close() 3871*cda5da8dSAndroid Build Coastguard Worker 3872*cda5da8dSAndroid Build Coastguard Workerdef read_docstrings(lang): 3873*cda5da8dSAndroid Build Coastguard Worker """Read in docstrings from lang-specific docstring dictionary. 3874*cda5da8dSAndroid Build Coastguard Worker 3875*cda5da8dSAndroid Build Coastguard Worker Transfer docstrings, translated to lang, from a dictionary-file 3876*cda5da8dSAndroid Build Coastguard Worker to the methods of classes Screen and Turtle and - in revised form - 3877*cda5da8dSAndroid Build Coastguard Worker to the corresponding functions. 3878*cda5da8dSAndroid Build Coastguard Worker """ 3879*cda5da8dSAndroid Build Coastguard Worker modname = "turtle_docstringdict_%(language)s" % {'language':lang.lower()} 3880*cda5da8dSAndroid Build Coastguard Worker module = __import__(modname) 3881*cda5da8dSAndroid Build Coastguard Worker docsdict = module.docsdict 3882*cda5da8dSAndroid Build Coastguard Worker for key in docsdict: 3883*cda5da8dSAndroid Build Coastguard Worker try: 3884*cda5da8dSAndroid Build Coastguard Worker# eval(key).im_func.__doc__ = docsdict[key] 3885*cda5da8dSAndroid Build Coastguard Worker eval(key).__doc__ = docsdict[key] 3886*cda5da8dSAndroid Build Coastguard Worker except Exception: 3887*cda5da8dSAndroid Build Coastguard Worker print("Bad docstring-entry: %s" % key) 3888*cda5da8dSAndroid Build Coastguard Worker 3889*cda5da8dSAndroid Build Coastguard Worker_LANGUAGE = _CFG["language"] 3890*cda5da8dSAndroid Build Coastguard Worker 3891*cda5da8dSAndroid Build Coastguard Workertry: 3892*cda5da8dSAndroid Build Coastguard Worker if _LANGUAGE != "english": 3893*cda5da8dSAndroid Build Coastguard Worker read_docstrings(_LANGUAGE) 3894*cda5da8dSAndroid Build Coastguard Workerexcept ImportError: 3895*cda5da8dSAndroid Build Coastguard Worker print("Cannot find docsdict for", _LANGUAGE) 3896*cda5da8dSAndroid Build Coastguard Workerexcept Exception: 3897*cda5da8dSAndroid Build Coastguard Worker print ("Unknown Error when trying to import %s-docstring-dictionary" % 3898*cda5da8dSAndroid Build Coastguard Worker _LANGUAGE) 3899*cda5da8dSAndroid Build Coastguard Worker 3900*cda5da8dSAndroid Build Coastguard Worker 3901*cda5da8dSAndroid Build Coastguard Workerdef getmethparlist(ob): 3902*cda5da8dSAndroid Build Coastguard Worker """Get strings describing the arguments for the given object 3903*cda5da8dSAndroid Build Coastguard Worker 3904*cda5da8dSAndroid Build Coastguard Worker Returns a pair of strings representing function parameter lists 3905*cda5da8dSAndroid Build Coastguard Worker including parenthesis. The first string is suitable for use in 3906*cda5da8dSAndroid Build Coastguard Worker function definition and the second is suitable for use in function 3907*cda5da8dSAndroid Build Coastguard Worker call. The "self" parameter is not included. 3908*cda5da8dSAndroid Build Coastguard Worker """ 3909*cda5da8dSAndroid Build Coastguard Worker defText = callText = "" 3910*cda5da8dSAndroid Build Coastguard Worker # bit of a hack for methods - turn it into a function 3911*cda5da8dSAndroid Build Coastguard Worker # but we drop the "self" param. 3912*cda5da8dSAndroid Build Coastguard Worker # Try and build one for Python defined functions 3913*cda5da8dSAndroid Build Coastguard Worker args, varargs, varkw = inspect.getargs(ob.__code__) 3914*cda5da8dSAndroid Build Coastguard Worker items2 = args[1:] 3915*cda5da8dSAndroid Build Coastguard Worker realArgs = args[1:] 3916*cda5da8dSAndroid Build Coastguard Worker defaults = ob.__defaults__ or [] 3917*cda5da8dSAndroid Build Coastguard Worker defaults = ["=%r" % (value,) for value in defaults] 3918*cda5da8dSAndroid Build Coastguard Worker defaults = [""] * (len(realArgs)-len(defaults)) + defaults 3919*cda5da8dSAndroid Build Coastguard Worker items1 = [arg + dflt for arg, dflt in zip(realArgs, defaults)] 3920*cda5da8dSAndroid Build Coastguard Worker if varargs is not None: 3921*cda5da8dSAndroid Build Coastguard Worker items1.append("*" + varargs) 3922*cda5da8dSAndroid Build Coastguard Worker items2.append("*" + varargs) 3923*cda5da8dSAndroid Build Coastguard Worker if varkw is not None: 3924*cda5da8dSAndroid Build Coastguard Worker items1.append("**" + varkw) 3925*cda5da8dSAndroid Build Coastguard Worker items2.append("**" + varkw) 3926*cda5da8dSAndroid Build Coastguard Worker defText = ", ".join(items1) 3927*cda5da8dSAndroid Build Coastguard Worker defText = "(%s)" % defText 3928*cda5da8dSAndroid Build Coastguard Worker callText = ", ".join(items2) 3929*cda5da8dSAndroid Build Coastguard Worker callText = "(%s)" % callText 3930*cda5da8dSAndroid Build Coastguard Worker return defText, callText 3931*cda5da8dSAndroid Build Coastguard Worker 3932*cda5da8dSAndroid Build Coastguard Workerdef _turtle_docrevise(docstr): 3933*cda5da8dSAndroid Build Coastguard Worker """To reduce docstrings from RawTurtle class for functions 3934*cda5da8dSAndroid Build Coastguard Worker """ 3935*cda5da8dSAndroid Build Coastguard Worker import re 3936*cda5da8dSAndroid Build Coastguard Worker if docstr is None: 3937*cda5da8dSAndroid Build Coastguard Worker return None 3938*cda5da8dSAndroid Build Coastguard Worker turtlename = _CFG["exampleturtle"] 3939*cda5da8dSAndroid Build Coastguard Worker newdocstr = docstr.replace("%s." % turtlename,"") 3940*cda5da8dSAndroid Build Coastguard Worker parexp = re.compile(r' \(.+ %s\):' % turtlename) 3941*cda5da8dSAndroid Build Coastguard Worker newdocstr = parexp.sub(":", newdocstr) 3942*cda5da8dSAndroid Build Coastguard Worker return newdocstr 3943*cda5da8dSAndroid Build Coastguard Worker 3944*cda5da8dSAndroid Build Coastguard Workerdef _screen_docrevise(docstr): 3945*cda5da8dSAndroid Build Coastguard Worker """To reduce docstrings from TurtleScreen class for functions 3946*cda5da8dSAndroid Build Coastguard Worker """ 3947*cda5da8dSAndroid Build Coastguard Worker import re 3948*cda5da8dSAndroid Build Coastguard Worker if docstr is None: 3949*cda5da8dSAndroid Build Coastguard Worker return None 3950*cda5da8dSAndroid Build Coastguard Worker screenname = _CFG["examplescreen"] 3951*cda5da8dSAndroid Build Coastguard Worker newdocstr = docstr.replace("%s." % screenname,"") 3952*cda5da8dSAndroid Build Coastguard Worker parexp = re.compile(r' \(.+ %s\):' % screenname) 3953*cda5da8dSAndroid Build Coastguard Worker newdocstr = parexp.sub(":", newdocstr) 3954*cda5da8dSAndroid Build Coastguard Worker return newdocstr 3955*cda5da8dSAndroid Build Coastguard Worker 3956*cda5da8dSAndroid Build Coastguard Worker## The following mechanism makes all methods of RawTurtle and Turtle available 3957*cda5da8dSAndroid Build Coastguard Worker## as functions. So we can enhance, change, add, delete methods to these 3958*cda5da8dSAndroid Build Coastguard Worker## classes and do not need to change anything here. 3959*cda5da8dSAndroid Build Coastguard Worker 3960*cda5da8dSAndroid Build Coastguard Worker__func_body = """\ 3961*cda5da8dSAndroid Build Coastguard Workerdef {name}{paramslist}: 3962*cda5da8dSAndroid Build Coastguard Worker if {obj} is None: 3963*cda5da8dSAndroid Build Coastguard Worker if not TurtleScreen._RUNNING: 3964*cda5da8dSAndroid Build Coastguard Worker TurtleScreen._RUNNING = True 3965*cda5da8dSAndroid Build Coastguard Worker raise Terminator 3966*cda5da8dSAndroid Build Coastguard Worker {obj} = {init} 3967*cda5da8dSAndroid Build Coastguard Worker try: 3968*cda5da8dSAndroid Build Coastguard Worker return {obj}.{name}{argslist} 3969*cda5da8dSAndroid Build Coastguard Worker except TK.TclError: 3970*cda5da8dSAndroid Build Coastguard Worker if not TurtleScreen._RUNNING: 3971*cda5da8dSAndroid Build Coastguard Worker TurtleScreen._RUNNING = True 3972*cda5da8dSAndroid Build Coastguard Worker raise Terminator 3973*cda5da8dSAndroid Build Coastguard Worker raise 3974*cda5da8dSAndroid Build Coastguard Worker""" 3975*cda5da8dSAndroid Build Coastguard Worker 3976*cda5da8dSAndroid Build Coastguard Workerdef _make_global_funcs(functions, cls, obj, init, docrevise): 3977*cda5da8dSAndroid Build Coastguard Worker for methodname in functions: 3978*cda5da8dSAndroid Build Coastguard Worker method = getattr(cls, methodname) 3979*cda5da8dSAndroid Build Coastguard Worker pl1, pl2 = getmethparlist(method) 3980*cda5da8dSAndroid Build Coastguard Worker if pl1 == "": 3981*cda5da8dSAndroid Build Coastguard Worker print(">>>>>>", pl1, pl2) 3982*cda5da8dSAndroid Build Coastguard Worker continue 3983*cda5da8dSAndroid Build Coastguard Worker defstr = __func_body.format(obj=obj, init=init, name=methodname, 3984*cda5da8dSAndroid Build Coastguard Worker paramslist=pl1, argslist=pl2) 3985*cda5da8dSAndroid Build Coastguard Worker exec(defstr, globals()) 3986*cda5da8dSAndroid Build Coastguard Worker globals()[methodname].__doc__ = docrevise(method.__doc__) 3987*cda5da8dSAndroid Build Coastguard Worker 3988*cda5da8dSAndroid Build Coastguard Worker_make_global_funcs(_tg_screen_functions, _Screen, 3989*cda5da8dSAndroid Build Coastguard Worker 'Turtle._screen', 'Screen()', _screen_docrevise) 3990*cda5da8dSAndroid Build Coastguard Worker_make_global_funcs(_tg_turtle_functions, Turtle, 3991*cda5da8dSAndroid Build Coastguard Worker 'Turtle._pen', 'Turtle()', _turtle_docrevise) 3992*cda5da8dSAndroid Build Coastguard Worker 3993*cda5da8dSAndroid Build Coastguard Worker 3994*cda5da8dSAndroid Build Coastguard Workerdone = mainloop 3995*cda5da8dSAndroid Build Coastguard Worker 3996*cda5da8dSAndroid Build Coastguard Workerif __name__ == "__main__": 3997*cda5da8dSAndroid Build Coastguard Worker def switchpen(): 3998*cda5da8dSAndroid Build Coastguard Worker if isdown(): 3999*cda5da8dSAndroid Build Coastguard Worker pu() 4000*cda5da8dSAndroid Build Coastguard Worker else: 4001*cda5da8dSAndroid Build Coastguard Worker pd() 4002*cda5da8dSAndroid Build Coastguard Worker 4003*cda5da8dSAndroid Build Coastguard Worker def demo1(): 4004*cda5da8dSAndroid Build Coastguard Worker """Demo of old turtle.py - module""" 4005*cda5da8dSAndroid Build Coastguard Worker reset() 4006*cda5da8dSAndroid Build Coastguard Worker tracer(True) 4007*cda5da8dSAndroid Build Coastguard Worker up() 4008*cda5da8dSAndroid Build Coastguard Worker backward(100) 4009*cda5da8dSAndroid Build Coastguard Worker down() 4010*cda5da8dSAndroid Build Coastguard Worker # draw 3 squares; the last filled 4011*cda5da8dSAndroid Build Coastguard Worker width(3) 4012*cda5da8dSAndroid Build Coastguard Worker for i in range(3): 4013*cda5da8dSAndroid Build Coastguard Worker if i == 2: 4014*cda5da8dSAndroid Build Coastguard Worker begin_fill() 4015*cda5da8dSAndroid Build Coastguard Worker for _ in range(4): 4016*cda5da8dSAndroid Build Coastguard Worker forward(20) 4017*cda5da8dSAndroid Build Coastguard Worker left(90) 4018*cda5da8dSAndroid Build Coastguard Worker if i == 2: 4019*cda5da8dSAndroid Build Coastguard Worker color("maroon") 4020*cda5da8dSAndroid Build Coastguard Worker end_fill() 4021*cda5da8dSAndroid Build Coastguard Worker up() 4022*cda5da8dSAndroid Build Coastguard Worker forward(30) 4023*cda5da8dSAndroid Build Coastguard Worker down() 4024*cda5da8dSAndroid Build Coastguard Worker width(1) 4025*cda5da8dSAndroid Build Coastguard Worker color("black") 4026*cda5da8dSAndroid Build Coastguard Worker # move out of the way 4027*cda5da8dSAndroid Build Coastguard Worker tracer(False) 4028*cda5da8dSAndroid Build Coastguard Worker up() 4029*cda5da8dSAndroid Build Coastguard Worker right(90) 4030*cda5da8dSAndroid Build Coastguard Worker forward(100) 4031*cda5da8dSAndroid Build Coastguard Worker right(90) 4032*cda5da8dSAndroid Build Coastguard Worker forward(100) 4033*cda5da8dSAndroid Build Coastguard Worker right(180) 4034*cda5da8dSAndroid Build Coastguard Worker down() 4035*cda5da8dSAndroid Build Coastguard Worker # some text 4036*cda5da8dSAndroid Build Coastguard Worker write("startstart", 1) 4037*cda5da8dSAndroid Build Coastguard Worker write("start", 1) 4038*cda5da8dSAndroid Build Coastguard Worker color("red") 4039*cda5da8dSAndroid Build Coastguard Worker # staircase 4040*cda5da8dSAndroid Build Coastguard Worker for i in range(5): 4041*cda5da8dSAndroid Build Coastguard Worker forward(20) 4042*cda5da8dSAndroid Build Coastguard Worker left(90) 4043*cda5da8dSAndroid Build Coastguard Worker forward(20) 4044*cda5da8dSAndroid Build Coastguard Worker right(90) 4045*cda5da8dSAndroid Build Coastguard Worker # filled staircase 4046*cda5da8dSAndroid Build Coastguard Worker tracer(True) 4047*cda5da8dSAndroid Build Coastguard Worker begin_fill() 4048*cda5da8dSAndroid Build Coastguard Worker for i in range(5): 4049*cda5da8dSAndroid Build Coastguard Worker forward(20) 4050*cda5da8dSAndroid Build Coastguard Worker left(90) 4051*cda5da8dSAndroid Build Coastguard Worker forward(20) 4052*cda5da8dSAndroid Build Coastguard Worker right(90) 4053*cda5da8dSAndroid Build Coastguard Worker end_fill() 4054*cda5da8dSAndroid Build Coastguard Worker # more text 4055*cda5da8dSAndroid Build Coastguard Worker 4056*cda5da8dSAndroid Build Coastguard Worker def demo2(): 4057*cda5da8dSAndroid Build Coastguard Worker """Demo of some new features.""" 4058*cda5da8dSAndroid Build Coastguard Worker speed(1) 4059*cda5da8dSAndroid Build Coastguard Worker st() 4060*cda5da8dSAndroid Build Coastguard Worker pensize(3) 4061*cda5da8dSAndroid Build Coastguard Worker setheading(towards(0, 0)) 4062*cda5da8dSAndroid Build Coastguard Worker radius = distance(0, 0)/2.0 4063*cda5da8dSAndroid Build Coastguard Worker rt(90) 4064*cda5da8dSAndroid Build Coastguard Worker for _ in range(18): 4065*cda5da8dSAndroid Build Coastguard Worker switchpen() 4066*cda5da8dSAndroid Build Coastguard Worker circle(radius, 10) 4067*cda5da8dSAndroid Build Coastguard Worker write("wait a moment...") 4068*cda5da8dSAndroid Build Coastguard Worker while undobufferentries(): 4069*cda5da8dSAndroid Build Coastguard Worker undo() 4070*cda5da8dSAndroid Build Coastguard Worker reset() 4071*cda5da8dSAndroid Build Coastguard Worker lt(90) 4072*cda5da8dSAndroid Build Coastguard Worker colormode(255) 4073*cda5da8dSAndroid Build Coastguard Worker laenge = 10 4074*cda5da8dSAndroid Build Coastguard Worker pencolor("green") 4075*cda5da8dSAndroid Build Coastguard Worker pensize(3) 4076*cda5da8dSAndroid Build Coastguard Worker lt(180) 4077*cda5da8dSAndroid Build Coastguard Worker for i in range(-2, 16): 4078*cda5da8dSAndroid Build Coastguard Worker if i > 0: 4079*cda5da8dSAndroid Build Coastguard Worker begin_fill() 4080*cda5da8dSAndroid Build Coastguard Worker fillcolor(255-15*i, 0, 15*i) 4081*cda5da8dSAndroid Build Coastguard Worker for _ in range(3): 4082*cda5da8dSAndroid Build Coastguard Worker fd(laenge) 4083*cda5da8dSAndroid Build Coastguard Worker lt(120) 4084*cda5da8dSAndroid Build Coastguard Worker end_fill() 4085*cda5da8dSAndroid Build Coastguard Worker laenge += 10 4086*cda5da8dSAndroid Build Coastguard Worker lt(15) 4087*cda5da8dSAndroid Build Coastguard Worker speed((speed()+1)%12) 4088*cda5da8dSAndroid Build Coastguard Worker #end_fill() 4089*cda5da8dSAndroid Build Coastguard Worker 4090*cda5da8dSAndroid Build Coastguard Worker lt(120) 4091*cda5da8dSAndroid Build Coastguard Worker pu() 4092*cda5da8dSAndroid Build Coastguard Worker fd(70) 4093*cda5da8dSAndroid Build Coastguard Worker rt(30) 4094*cda5da8dSAndroid Build Coastguard Worker pd() 4095*cda5da8dSAndroid Build Coastguard Worker color("red","yellow") 4096*cda5da8dSAndroid Build Coastguard Worker speed(0) 4097*cda5da8dSAndroid Build Coastguard Worker begin_fill() 4098*cda5da8dSAndroid Build Coastguard Worker for _ in range(4): 4099*cda5da8dSAndroid Build Coastguard Worker circle(50, 90) 4100*cda5da8dSAndroid Build Coastguard Worker rt(90) 4101*cda5da8dSAndroid Build Coastguard Worker fd(30) 4102*cda5da8dSAndroid Build Coastguard Worker rt(90) 4103*cda5da8dSAndroid Build Coastguard Worker end_fill() 4104*cda5da8dSAndroid Build Coastguard Worker lt(90) 4105*cda5da8dSAndroid Build Coastguard Worker pu() 4106*cda5da8dSAndroid Build Coastguard Worker fd(30) 4107*cda5da8dSAndroid Build Coastguard Worker pd() 4108*cda5da8dSAndroid Build Coastguard Worker shape("turtle") 4109*cda5da8dSAndroid Build Coastguard Worker 4110*cda5da8dSAndroid Build Coastguard Worker tri = getturtle() 4111*cda5da8dSAndroid Build Coastguard Worker tri.resizemode("auto") 4112*cda5da8dSAndroid Build Coastguard Worker turtle = Turtle() 4113*cda5da8dSAndroid Build Coastguard Worker turtle.resizemode("auto") 4114*cda5da8dSAndroid Build Coastguard Worker turtle.shape("turtle") 4115*cda5da8dSAndroid Build Coastguard Worker turtle.reset() 4116*cda5da8dSAndroid Build Coastguard Worker turtle.left(90) 4117*cda5da8dSAndroid Build Coastguard Worker turtle.speed(0) 4118*cda5da8dSAndroid Build Coastguard Worker turtle.up() 4119*cda5da8dSAndroid Build Coastguard Worker turtle.goto(280, 40) 4120*cda5da8dSAndroid Build Coastguard Worker turtle.lt(30) 4121*cda5da8dSAndroid Build Coastguard Worker turtle.down() 4122*cda5da8dSAndroid Build Coastguard Worker turtle.speed(6) 4123*cda5da8dSAndroid Build Coastguard Worker turtle.color("blue","orange") 4124*cda5da8dSAndroid Build Coastguard Worker turtle.pensize(2) 4125*cda5da8dSAndroid Build Coastguard Worker tri.speed(6) 4126*cda5da8dSAndroid Build Coastguard Worker setheading(towards(turtle)) 4127*cda5da8dSAndroid Build Coastguard Worker count = 1 4128*cda5da8dSAndroid Build Coastguard Worker while tri.distance(turtle) > 4: 4129*cda5da8dSAndroid Build Coastguard Worker turtle.fd(3.5) 4130*cda5da8dSAndroid Build Coastguard Worker turtle.lt(0.6) 4131*cda5da8dSAndroid Build Coastguard Worker tri.setheading(tri.towards(turtle)) 4132*cda5da8dSAndroid Build Coastguard Worker tri.fd(4) 4133*cda5da8dSAndroid Build Coastguard Worker if count % 20 == 0: 4134*cda5da8dSAndroid Build Coastguard Worker turtle.stamp() 4135*cda5da8dSAndroid Build Coastguard Worker tri.stamp() 4136*cda5da8dSAndroid Build Coastguard Worker switchpen() 4137*cda5da8dSAndroid Build Coastguard Worker count += 1 4138*cda5da8dSAndroid Build Coastguard Worker tri.write("CAUGHT! ", font=("Arial", 16, "bold"), align="right") 4139*cda5da8dSAndroid Build Coastguard Worker tri.pencolor("black") 4140*cda5da8dSAndroid Build Coastguard Worker tri.pencolor("red") 4141*cda5da8dSAndroid Build Coastguard Worker 4142*cda5da8dSAndroid Build Coastguard Worker def baba(xdummy, ydummy): 4143*cda5da8dSAndroid Build Coastguard Worker clearscreen() 4144*cda5da8dSAndroid Build Coastguard Worker bye() 4145*cda5da8dSAndroid Build Coastguard Worker 4146*cda5da8dSAndroid Build Coastguard Worker time.sleep(2) 4147*cda5da8dSAndroid Build Coastguard Worker 4148*cda5da8dSAndroid Build Coastguard Worker while undobufferentries(): 4149*cda5da8dSAndroid Build Coastguard Worker tri.undo() 4150*cda5da8dSAndroid Build Coastguard Worker turtle.undo() 4151*cda5da8dSAndroid Build Coastguard Worker tri.fd(50) 4152*cda5da8dSAndroid Build Coastguard Worker tri.write(" Click me!", font = ("Courier", 12, "bold") ) 4153*cda5da8dSAndroid Build Coastguard Worker tri.onclick(baba, 1) 4154*cda5da8dSAndroid Build Coastguard Worker 4155*cda5da8dSAndroid Build Coastguard Worker demo1() 4156*cda5da8dSAndroid Build Coastguard Worker demo2() 4157*cda5da8dSAndroid Build Coastguard Worker exitonclick() 4158