turtleshell 1.1.0__py3-none-any.whl → 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- turtleshell/__init__.py +1 -1
- turtleshell/core.py +185 -68
- {turtleshell-1.1.0.dist-info → turtleshell-1.3.0.dist-info}/METADATA +1 -1
- turtleshell-1.3.0.dist-info/RECORD +6 -0
- {turtleshell-1.1.0.dist-info → turtleshell-1.3.0.dist-info}/WHEEL +1 -1
- {turtleshell-1.1.0.dist-info → turtleshell-1.3.0.dist-info}/top_level.txt +0 -0
- turtleshell-1.1.0.dist-info/RECORD +0 -6
turtleshell/__init__.py
CHANGED
turtleshell/core.py
CHANGED
@@ -2,10 +2,12 @@
|
|
2
2
|
See https://github.com/python/cpython/blob/main/Lib/turtle.py
|
3
3
|
"""
|
4
4
|
#TODO handle floats, randcoords, default screensize, default shape
|
5
|
+
#TODO # def _polytrafo(self, poly):
|
5
6
|
|
6
|
-
import colorsys
|
7
|
+
import colorsys, math, turtle
|
7
8
|
from dataclasses import dataclass
|
8
|
-
|
9
|
+
|
10
|
+
sign = lambda x: round(math.copysign(1, x))
|
9
11
|
|
10
12
|
@dataclass
|
11
13
|
class HSV:
|
@@ -28,9 +30,63 @@ class _Screen(turtle._Screen):
|
|
28
30
|
if turtle.Turtle._screen is None:
|
29
31
|
turtle.Turtle._screen = self
|
30
32
|
self.colormode(255)
|
33
|
+
self.timers = {}
|
34
|
+
|
35
|
+
@property
|
36
|
+
def width(self):
|
37
|
+
return self.window_width()
|
38
|
+
|
39
|
+
@property
|
40
|
+
def height(self):
|
41
|
+
return self.window_height()
|
31
42
|
|
43
|
+
def setup(self, width=turtle._CFG["width"], height=turtle._CFG["height"],
|
44
|
+
startx=turtle._CFG["leftright"], starty=turtle._CFG["topbottom"]):
|
45
|
+
super().setup(width, height, startx, starty)
|
46
|
+
self.screensize(self.width-20, self.height-20)
|
47
|
+
|
48
|
+
def _onkeypress(self, fun, key=None):
|
49
|
+
if fun is None:
|
50
|
+
if key is None:
|
51
|
+
for key in self._keys:
|
52
|
+
self._keys.remove(key)
|
53
|
+
self.cv.unbind("<KeyPress-%s>" % key, None)
|
54
|
+
else:
|
55
|
+
self.cv.unbind("<KeyPress-%s>" % key, None)
|
56
|
+
else:
|
57
|
+
def eventfun(event):
|
58
|
+
fun()
|
59
|
+
if key is None:
|
60
|
+
self.cv.bind("<KeyPress>", eventfun)
|
61
|
+
else:
|
62
|
+
self.cv.bind("<KeyPress-%s>" % key, eventfun)
|
63
|
+
|
64
|
+
def onmove(self, fun):
|
65
|
+
def eventfun(event):
|
66
|
+
x, y = (self.cv.canvasx(event.x)/self.xscale,
|
67
|
+
-self.cv.canvasy(event.y)/self.yscale)
|
68
|
+
fun(x, y)
|
69
|
+
self.cv.bind("<Motion>", eventfun)
|
70
|
+
|
71
|
+
def cancel_timer(self, func):
|
72
|
+
if not func in self.timers:
|
73
|
+
return
|
74
|
+
for id in self.timers.pop(func):
|
75
|
+
self.getcanvas().after_cancel(id)
|
76
|
+
|
77
|
+
def set_timer(self, func, ms, add=False):
|
78
|
+
if not add and func in self.timers:
|
79
|
+
self.cancel_timer(func)
|
80
|
+
id = self.getcanvas().after(ms, func)
|
81
|
+
if func in self.timers:
|
82
|
+
self.timers[func].append(id)
|
83
|
+
else:
|
84
|
+
self.timers[func] = [id]
|
85
|
+
|
32
86
|
def _colorstr(self, color):
|
33
87
|
isnumber = lambda x: isinstance(x, (int, float))
|
88
|
+
if isinstance(color, tuple) and len(color) == 1:
|
89
|
+
color = color[0]
|
34
90
|
if len(color) == 3 and all([isnumber(c) for c in color]):
|
35
91
|
lower, upper = 0, Turtle._screen.colormode()
|
36
92
|
color = [max(min(upper, round(c)), lower) for c in color]
|
@@ -60,6 +116,52 @@ class Turtle(turtle.RawTurtle):
|
|
60
116
|
self._pen_hsv = HSV(0, 1, 1)
|
61
117
|
self._fill_hsv = HSV(0, 1, 1)
|
62
118
|
|
119
|
+
def __lt__(self, other):
|
120
|
+
if isinstance(other, Turtle):
|
121
|
+
return self.y < other.y
|
122
|
+
return NotImplemented
|
123
|
+
|
124
|
+
def __eq__(self, other):
|
125
|
+
if isinstance(other, Turtle):
|
126
|
+
return self.y == other.y
|
127
|
+
return NotImplemented
|
128
|
+
|
129
|
+
def onenter(self, fun):
|
130
|
+
titem = self.turtle._item
|
131
|
+
if fun is None:
|
132
|
+
self.screen.cv.tag_unbind(titem, "<Enter>")
|
133
|
+
else:
|
134
|
+
def eventfun(event):
|
135
|
+
x, y = (self.screen.cv.canvasx(event.x)/self.screen.xscale,
|
136
|
+
-self.screen.cv.canvasy(event.y)/self.screen.yscale)
|
137
|
+
fun(x, y)
|
138
|
+
self.screen.cv.tag_bind(titem, "<Enter>", eventfun)
|
139
|
+
|
140
|
+
def onexit(self, fun):
|
141
|
+
titem = self.turtle._item
|
142
|
+
if fun is None:
|
143
|
+
self.screen.cv.tag_unbind(titem, "<Leave>")
|
144
|
+
else:
|
145
|
+
def eventfun(event):
|
146
|
+
x, y = (self.screen.cv.canvasx(event.x)/self.screen.xscale,
|
147
|
+
-self.screen.cv.canvasy(event.y)/self.screen.yscale)
|
148
|
+
fun(x, y)
|
149
|
+
self.screen.cv.tag_bind(titem, "<Leave>", eventfun)
|
150
|
+
|
151
|
+
def bring_forward(self):
|
152
|
+
titem = self.turtle._item
|
153
|
+
for item in self.items:
|
154
|
+
self.screen.cv.tag_raise(item)
|
155
|
+
titem = self.turtle._item
|
156
|
+
self.screen.cv.tag_raise(titem)
|
157
|
+
|
158
|
+
def send_backward(self):
|
159
|
+
titem = self.turtle._item
|
160
|
+
self.screen.cv.tag_lower(titem)
|
161
|
+
|
162
|
+
def face(self, x, y):
|
163
|
+
self.setheading(self.towards(x, y))
|
164
|
+
|
63
165
|
@property
|
64
166
|
def x(self):
|
65
167
|
return self.xcor()
|
@@ -76,99 +178,114 @@ class Turtle(turtle.RawTurtle):
|
|
76
178
|
def y(self, value):
|
77
179
|
self.sety(value)
|
78
180
|
|
79
|
-
|
80
|
-
def shapewidth(self):
|
81
|
-
xcoords = [vertex[0] for vertex in self.get_shapepoly()]
|
82
|
-
return max(xcoords) - min(xcoords)
|
181
|
+
def shapesize(self, stretch_wid=None, stretch_len=None, outline=None):
|
83
182
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
183
|
+
if stretch_wid is None and stretch_len is None and outline is None:
|
184
|
+
stretch_wid, stretch_len, outline = super().shapesize()
|
185
|
+
return stretch_wid*Turtle.MULT, stretch_len*Turtle.MULT, outline
|
186
|
+
|
187
|
+
stretch_wid = stretch_wid/Turtle.MULT if stretch_wid else None
|
188
|
+
stretch_len = stretch_len/Turtle.MULT if stretch_len else None
|
189
|
+
ret = super().shapesize(stretch_wid, stretch_len, outline)
|
190
|
+
return ret
|
191
|
+
|
192
|
+
def teleport(self, x, y):
|
193
|
+
pendown = self.isdown()
|
194
|
+
if pendown:
|
195
|
+
self.pen(pendown=False)
|
196
|
+
self.penup()
|
197
|
+
self._position = turtle.Vec2D(x, y)
|
198
|
+
self.pen(pendown=pendown)
|
199
|
+
|
200
|
+
def _write(self, txt, align, font):
|
201
|
+
"""Performs the writing for write()
|
202
|
+
"""
|
203
|
+
item, end = self.screen._write(self._position, txt, align, font,
|
204
|
+
self._pencolor)
|
205
|
+
|
206
|
+
self._update()
|
207
|
+
self.items.append(item)
|
208
|
+
if self.undobuffer:
|
209
|
+
self.undobuffer.push(("wri", item))
|
210
|
+
return end
|
211
|
+
|
212
|
+
def write(self, arg, move=False, align="center", font=("Courier New", 20, "bold")):
|
213
|
+
super().write(arg, move, align, font)
|
214
|
+
self.bring_forward() # TODO this will be undone if Screen.update() is called
|
215
|
+
|
216
|
+
def to_front(self):
|
217
|
+
self.goto(self.position())
|
88
218
|
|
89
|
-
|
90
|
-
|
91
|
-
|
219
|
+
## HSV colour methods
|
220
|
+
def hsv(self, hue, sat, val):
|
221
|
+
return
|
92
222
|
|
93
|
-
def
|
223
|
+
def penhsv(self, *args):
|
224
|
+
print(args)
|
225
|
+
|
226
|
+
def fillhsv(self, *args):
|
227
|
+
print(args)
|
228
|
+
|
229
|
+
def hue(self, degrees=None):
|
230
|
+
return (self.penhue(degrees), self.fillhue(degrees))
|
231
|
+
|
232
|
+
def penhue(self, degrees=None):
|
233
|
+
if degrees is None:
|
234
|
+
return self._pen_hsv.hue * 360
|
94
235
|
self._pen_hsv.hue = degrees/360
|
95
236
|
self.pencolor(_hsv_to_rgb(self._pen_hsv))
|
237
|
+
return degrees
|
96
238
|
|
97
|
-
def fillhue(self, degrees):
|
239
|
+
def fillhue(self, degrees=None):
|
240
|
+
if degrees is None:
|
241
|
+
return self._fill_hsv.hue * 360
|
98
242
|
self._fill_hsv.hue = degrees/360
|
99
243
|
self.fillcolor(_hsv_to_rgb(self._fill_hsv))
|
100
244
|
|
101
|
-
def sat(self, value):
|
102
|
-
self.pensat(value)
|
103
|
-
self.fillsat(value)
|
245
|
+
def sat(self, value=None):
|
246
|
+
return(self.pensat(value), self.fillsat(value))
|
104
247
|
|
105
|
-
def pensat(self, value):
|
248
|
+
def pensat(self, value=None):
|
249
|
+
if value is None:
|
250
|
+
return self._pen_hsv.sat * 100
|
106
251
|
self._pen_hsv.sat = value/100
|
107
252
|
self.pencolor(_hsv_to_rgb(self._pen_hsv))
|
108
253
|
|
109
|
-
def fillsat(self, value):
|
254
|
+
def fillsat(self, value=None):
|
255
|
+
if value is None:
|
256
|
+
return self._fill_hsv.sat * 100
|
110
257
|
self._fill_hsv.sat = value/100
|
111
258
|
self.fillcolor(_hsv_to_rgb(self._fill_hsv))
|
112
259
|
|
113
|
-
def val(self, value):
|
114
|
-
self.penval(value)
|
115
|
-
self.fillval(value)
|
260
|
+
def val(self, value=None):
|
261
|
+
return (self.penval(value), self.fillval(value))
|
116
262
|
|
117
|
-
def penval(self, value):
|
263
|
+
def penval(self, value=None):
|
264
|
+
if value is None:
|
265
|
+
return self._pen_hsv.val * 100
|
118
266
|
self._pen_hsv.val = value/100
|
119
267
|
self.pencolor(_hsv_to_rgb(self._pen_hsv))
|
120
268
|
|
121
|
-
def fillval(self, value):
|
269
|
+
def fillval(self, value=None):
|
270
|
+
if value is None:
|
271
|
+
return self._fill_hsv.val * 100
|
122
272
|
self._fill_hsv.val = value/100
|
123
273
|
self.fillcolor(_hsv_to_rgb(self._fill_hsv))
|
124
274
|
|
125
|
-
def shapesize(self, stretch_wid=None, stretch_len=None, outline=None):
|
126
|
-
if stretch_wid is None and stretch_len is None and outline is None:
|
127
|
-
stretch_wid, stretch_len, outline = super().shapesize()
|
128
|
-
return stretch_wid*Turtle.MULT, stretch_len*Turtle.MULT, outline
|
129
|
-
|
130
|
-
stretch_wid = stretch_wid/Turtle.MULT if stretch_wid else None
|
131
|
-
stretch_len = stretch_len/Turtle.MULT if stretch_len else None
|
132
|
-
ret = super().shapesize(stretch_wid, stretch_len, outline)
|
133
|
-
return ret
|
134
|
-
|
135
|
-
def teleport(self, x, y):
|
136
|
-
pendown = self.isdown()
|
137
|
-
if pendown:
|
138
|
-
self.pen(pendown=False)
|
139
|
-
self.penup()
|
140
|
-
self._position = turtle.Vec2D(x, y)
|
141
|
-
self.pen(pendown=pendown)
|
142
|
-
|
143
|
-
def write(self, arg, move=False, align="center", font=("Arial", 18, "bold")):
|
144
|
-
super().write(arg, move, align, font)
|
145
|
-
|
146
275
|
Pen = Turtle
|
147
276
|
|
148
|
-
|
149
|
-
canvas = Screen()
|
150
|
-
canvas.bgcolor("gold")
|
277
|
+
def turtle_test(screen):
|
151
278
|
pen = Turtle()
|
152
|
-
print(f"\n\n***\nTURTLE TYPE: {type(pen)}\nSCREEN TYPE: {type(
|
153
|
-
|
279
|
+
print(f"\n\n***\nTURTLE TYPE: {type(pen)}\nSCREEN TYPE: {type(screen)}\n***\n")
|
154
280
|
pen.shape("square")
|
155
|
-
print(f"{pen.shapewidth}, {pen.shapeheight}")
|
156
281
|
pen.shapesize(30, 25)
|
157
|
-
|
158
|
-
|
159
|
-
pen.hue(0)
|
160
|
-
pen.stamp()
|
161
|
-
pen.forward(50)
|
162
|
-
pen.hue(60)
|
163
|
-
pen.stamp()
|
164
|
-
pen.forward(50)
|
165
|
-
pen.hue(120)
|
166
|
-
pen.stamp()
|
167
|
-
pen.forward(50)
|
168
|
-
pen.hue(180)
|
169
|
-
pen.stamp()
|
170
|
-
pen.forward(50)
|
171
|
-
pen.hue(240)
|
282
|
+
pen.hsv(100, 50, 50)
|
172
283
|
pen.stamp()
|
173
284
|
|
174
|
-
|
285
|
+
if __name__ == "__main__":
|
286
|
+
import os;os.system("clear")
|
287
|
+
screen = Screen()
|
288
|
+
screen.setup(400,400,0,0)
|
289
|
+
screen.bgcolor("gold")
|
290
|
+
turtle_test(screen)
|
291
|
+
screen.exitonclick()
|
@@ -0,0 +1,6 @@
|
|
1
|
+
turtleshell/__init__.py,sha256=nfmP05Yjc-GIAHSUHj5DygwbICrHuGnvve6YY8vMbSo,55
|
2
|
+
turtleshell/core.py,sha256=_zMqr3Y2LWZA6mQ4o-EdtIkzB1Any8IPwsKT019pnns,8526
|
3
|
+
turtleshell-1.3.0.dist-info/METADATA,sha256=UDmbh5_jZlNDeii-ZK5WKhwcgaigdQlVhvPzTv_W3oc,1124
|
4
|
+
turtleshell-1.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
5
|
+
turtleshell-1.3.0.dist-info/top_level.txt,sha256=nIp6ZtgikYbeYxpXq6zs04zeIaXIMs3ZzAx5QREfkYM,12
|
6
|
+
turtleshell-1.3.0.dist-info/RECORD,,
|
File without changes
|
@@ -1,6 +0,0 @@
|
|
1
|
-
turtleshell/__init__.py,sha256=ESul5N9bShIY7Z0FuUui9-D-dWtgelBrhqe9P5oYZp4,55
|
2
|
-
turtleshell/core.py,sha256=ZwYPwarjk7P0Lo1ELFx_8kh4I3H2ZXs1th85U5Vuuts,4709
|
3
|
-
turtleshell-1.1.0.dist-info/METADATA,sha256=Mf38yRHRyL02a1J7oJ9A0d-I3CElSmssLG7DSKQqHZI,1124
|
4
|
-
turtleshell-1.1.0.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
|
5
|
-
turtleshell-1.1.0.dist-info/top_level.txt,sha256=nIp6ZtgikYbeYxpXq6zs04zeIaXIMs3ZzAx5QREfkYM,12
|
6
|
-
turtleshell-1.1.0.dist-info/RECORD,,
|