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 CHANGED
@@ -1,3 +1,3 @@
1
1
  from .core import Screen, Turtle
2
2
 
3
- __version__ = "1.1.0"
3
+ __version__ = "1.3.0"
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
- import turtle
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
- @property
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
- @property
85
- def shapeheight(self):
86
- ycoords = [vertex[1] for vertex in self.get_shapepoly()]
87
- return max(ycoords) - min(ycoords)
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
- def hue(self, degrees):
90
- self.penhue(degrees)
91
- self.fillhue(degrees)
219
+ ## HSV colour methods
220
+ def hsv(self, hue, sat, val):
221
+ return
92
222
 
93
- def penhue(self, degrees):
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
- if __name__ == "__main__":
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(canvas)}\n***\n")
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
- print(f"{pen.shapewidth}, {pen.shapeheight}")
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
- canvas.exitonclick()
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()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: turtleshell
3
- Version: 1.1.0
3
+ Version: 1.3.0
4
4
  Summary: Convenience wrapper around turtle.Turtle and turtle.Screen
5
5
  Author-email: Sam Mangan <sam.mangan2@gmail.com>
6
6
  License-Expression: MIT
@@ -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,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.7.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -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,,