turtleshell 1.2.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 +163 -40
- {turtleshell-1.2.0.dist-info → turtleshell-1.3.0.dist-info}/METADATA +1 -1
- turtleshell-1.3.0.dist-info/RECORD +6 -0
- {turtleshell-1.2.0.dist-info → turtleshell-1.3.0.dist-info}/WHEEL +1 -1
- turtleshell-1.2.0.dist-info/RECORD +0 -6
- {turtleshell-1.2.0.dist-info → turtleshell-1.3.0.dist-info}/top_level.txt +0 -0
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()
|
31
38
|
|
39
|
+
@property
|
40
|
+
def height(self):
|
41
|
+
return self.window_height()
|
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()
|
@@ -94,75 +196,96 @@ class Turtle(turtle.RawTurtle):
|
|
94
196
|
self.penup()
|
95
197
|
self._position = turtle.Vec2D(x, y)
|
96
198
|
self.pen(pendown=pendown)
|
97
|
-
|
98
|
-
def
|
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")):
|
99
213
|
super().write(arg, move, align, font)
|
214
|
+
self.bring_forward() # TODO this will be undone if Screen.update() is called
|
100
215
|
|
101
216
|
def to_front(self):
|
102
217
|
self.goto(self.position())
|
103
218
|
|
104
219
|
## HSV colour methods
|
105
|
-
def
|
106
|
-
|
107
|
-
self.fillhue(degrees)
|
220
|
+
def hsv(self, hue, sat, val):
|
221
|
+
return
|
108
222
|
|
109
|
-
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
|
110
235
|
self._pen_hsv.hue = degrees/360
|
111
236
|
self.pencolor(_hsv_to_rgb(self._pen_hsv))
|
237
|
+
return degrees
|
112
238
|
|
113
|
-
def fillhue(self, degrees):
|
239
|
+
def fillhue(self, degrees=None):
|
240
|
+
if degrees is None:
|
241
|
+
return self._fill_hsv.hue * 360
|
114
242
|
self._fill_hsv.hue = degrees/360
|
115
243
|
self.fillcolor(_hsv_to_rgb(self._fill_hsv))
|
116
244
|
|
117
|
-
def sat(self, value):
|
118
|
-
self.pensat(value)
|
119
|
-
self.fillsat(value)
|
245
|
+
def sat(self, value=None):
|
246
|
+
return(self.pensat(value), self.fillsat(value))
|
120
247
|
|
121
|
-
def pensat(self, value):
|
248
|
+
def pensat(self, value=None):
|
249
|
+
if value is None:
|
250
|
+
return self._pen_hsv.sat * 100
|
122
251
|
self._pen_hsv.sat = value/100
|
123
252
|
self.pencolor(_hsv_to_rgb(self._pen_hsv))
|
124
253
|
|
125
|
-
def fillsat(self, value):
|
254
|
+
def fillsat(self, value=None):
|
255
|
+
if value is None:
|
256
|
+
return self._fill_hsv.sat * 100
|
126
257
|
self._fill_hsv.sat = value/100
|
127
258
|
self.fillcolor(_hsv_to_rgb(self._fill_hsv))
|
128
259
|
|
129
|
-
def val(self, value):
|
130
|
-
self.penval(value)
|
131
|
-
self.fillval(value)
|
260
|
+
def val(self, value=None):
|
261
|
+
return (self.penval(value), self.fillval(value))
|
132
262
|
|
133
|
-
def penval(self, value):
|
263
|
+
def penval(self, value=None):
|
264
|
+
if value is None:
|
265
|
+
return self._pen_hsv.val * 100
|
134
266
|
self._pen_hsv.val = value/100
|
135
267
|
self.pencolor(_hsv_to_rgb(self._pen_hsv))
|
136
268
|
|
137
|
-
def fillval(self, value):
|
269
|
+
def fillval(self, value=None):
|
270
|
+
if value is None:
|
271
|
+
return self._fill_hsv.val * 100
|
138
272
|
self._fill_hsv.val = value/100
|
139
273
|
self.fillcolor(_hsv_to_rgb(self._fill_hsv))
|
140
274
|
|
141
|
-
|
142
275
|
Pen = Turtle
|
143
276
|
|
144
|
-
|
145
|
-
canvas = Screen()
|
146
|
-
canvas.bgcolor("gold")
|
277
|
+
def turtle_test(screen):
|
147
278
|
pen = Turtle()
|
148
|
-
print(f"\n\n***\nTURTLE TYPE: {type(pen)}\nSCREEN TYPE: {type(
|
149
|
-
|
279
|
+
print(f"\n\n***\nTURTLE TYPE: {type(pen)}\nSCREEN TYPE: {type(screen)}\n***\n")
|
150
280
|
pen.shape("square")
|
151
281
|
pen.shapesize(30, 25)
|
152
|
-
|
153
|
-
pen.hue(0)
|
154
|
-
pen.stamp()
|
155
|
-
pen.forward(50)
|
156
|
-
pen.hue(60)
|
157
|
-
pen.stamp()
|
158
|
-
pen.forward(50)
|
159
|
-
pen.hue(120)
|
160
|
-
pen.stamp()
|
161
|
-
pen.forward(50)
|
162
|
-
pen.hue(180)
|
163
|
-
pen.stamp()
|
164
|
-
pen.forward(50)
|
165
|
-
pen.hue(240)
|
282
|
+
pen.hsv(100, 50, 50)
|
166
283
|
pen.stamp()
|
167
284
|
|
168
|
-
|
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,,
|
@@ -1,6 +0,0 @@
|
|
1
|
-
turtleshell/__init__.py,sha256=85lJZi_-C3nKgx2AqgwkiuvLjk3pBtACIQynLTj7nSc,55
|
2
|
-
turtleshell/core.py,sha256=WYMtNv225fTi55bfxDqJhem25E18TNqJl116j77Rl5A,4410
|
3
|
-
turtleshell-1.2.0.dist-info/METADATA,sha256=C6XQ5TfWKndLSBhkKHOqyVUc44zH8nKi3wuaaXUaSl0,1124
|
4
|
-
turtleshell-1.2.0.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
|
5
|
-
turtleshell-1.2.0.dist-info/top_level.txt,sha256=nIp6ZtgikYbeYxpXq6zs04zeIaXIMs3ZzAx5QREfkYM,12
|
6
|
-
turtleshell-1.2.0.dist-info/RECORD,,
|
File without changes
|