Skip to content

Commit e53ad8b

Browse files
committed
Version 1.1.143-158
* The `is_clicked()` function of the `GraphicsObject` class returns whether or not the object's `bounds` were clicked. If it has no bounds, it returns `False` * Made the `RadioButton` class an iterable * You can now use the `len()` function on `RadioButton` and `CycleButton` objects * The `RadioButton` and `CycleButton` classes are now subscriptable * Added an `anchor` attribute to the `CycleButton` class to support gliding * The `RadioButton` and `CycleButton` classes now support movement and gliding functions * The `get_anchor()` function of the `CycleButton` class now returns the value from its states' `get_anchor()` function, not the `anchor` attribute itself * The `is_clicked()` function in the `Image()` class now uses integer division (`//`) rather than float division (`/`) to make it slightly faster and also pre-calculates the divisions to perform half the division operations * Fixed bug with the `RadioButton` & `CycleButton` class not changing their anchors when moving * Fixed bug with all the `GraphicsObject`glide functions adding 2 lists together instead of their elements * The `RadioButton` class now raises an error if the user has specified 0 states * Added a `get_anchor()` function to the `RadioButton` class * Fixed bug with `Button` objects not defining their `anchor` during the initialization * The `change_graphic()` function of the `Button` class now allows you to set graphics to `None` * The `GraphicObject` class now raises an error if the user tries to glide an object which does not support it * Renamed the `allow_only_numeric()` function of the `Entry` to `allow_only_positive_integer()` and added 2 new functions: `allow_only_numeric()` and `allow_only_integer()`
1 parent e63923f commit e53ad8b

File tree

9 files changed

+210
-36
lines changed

9 files changed

+210
-36
lines changed

MathFeatures.png

-61.3 KB
Binary file not shown.

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,35 @@ https://stackoverflow.com/questions/63978464/error-when-compiling-cpython-cannot
206206
There are probably still a lot of bugs in the release version, but I moved onto Version 1.1 because I started working
207207
on converting goopylib code to Cython C and also building a Sound Engine for goopylib 1.2
208208

209+
#### 1.1.158-alpha18 3rd November 2020
210+
211+
* The `is_clicked()` function of the `GraphicsObject` class returns whether or not the object's `bounds` were clicked.
212+
If it has no bounds, it returns `False`
213+
214+
* Made the `RadioButton` class an iterable
215+
* You can now use the `len()` function on `RadioButton` and `CycleButton` objects
216+
* The `RadioButton` and `CycleButton` classes are now subscriptable
217+
* Added an `anchor` attribute to the `CycleButton` class to support gliding
218+
219+
* The `RadioButton` and `CycleButton` classes now support movement and gliding functions
220+
* The `get_anchor()` function of the `CycleButton` class now returns the value from its states' `get_anchor()` function,
221+
not the `anchor` attribute itself
222+
223+
* The `is_clicked()` function in the `Image()` class now uses integer division (`//`) rather than float division (`/`)
224+
to make it slightly faster and also pre-calculates the divisions to perform half the division operations
225+
226+
* Fixed bug with the `RadioButton` & `CycleButton` class not changing their anchors when moving
227+
* Fixed bug with all the `GraphicsObject`glide functions adding 2 lists together instead of their elements
228+
* The `RadioButton` class now raises an error if the user has specified 0 states
229+
230+
* Added a `get_anchor()` function to the `RadioButton` class
231+
* Fixed bug with `Button` objects not defining their `anchor` during the initialization
232+
* The `change_graphic()` function of the `Button` class now allows you to set graphics to `None`
233+
234+
* The `GraphicObject` class now raises an error if the user tries to glide an object which does not support it
235+
* Renamed the `allow_only_numeric()` function of the `Entry` to `allow_only_positive_integer()` and added 2 new
236+
functions: `allow_only_numeric()` and `allow_only_integer()`
237+
209238
#### 1.1.142-alpha17 1st-2nd November 2020
210239

211240
* Fixed bug with the default Image Texture path being `textures_other/` instead of `textures/`

goopylib/objects/Button.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def __init__(self, graphic, hover_graphic=None, clicked_graphic=None, disabled_g
2929
self.disabled_graphic_given = False
3030

3131
self.graphic = self.normal_graphic
32+
self.anchor = self.graphic.anchor
3233
self.drawn_graphic = self.graphic
3334

3435
self.label = label
@@ -52,7 +53,7 @@ def _draw(self, canvas, options):
5253
self.label.draw(canvas, _internal_call=True)
5354

5455
def destroy(self):
55-
GraphicsObject.objects.remove(self)
56+
GraphicsObject.objects.discard(self)
5657
GraphicsObject.object_layers[self.layer].discard(self)
5758
GraphicsObject.draggable_objects.discard(self)
5859
GraphicsObject.cursor_objects.discard(self)
@@ -160,18 +161,18 @@ def set_enabled(self, enable):
160161
else:
161162
self.disable()
162163

163-
def change_graphic(self, graphic=None, hover_graphic=None, clicked_graphic=None, disabled_graphic=None, label=None):
164+
def change_graphic(self, graphic=0, hover_graphic=0, clicked_graphic=0, disabled_graphic=0, label=0):
164165
self.undraw()
165-
if hover_graphic is not None:
166+
if hover_graphic != 0:
166167
self.hover_graphic = hover_graphic
167-
if graphic is not None:
168+
if graphic != 0:
168169
self.normal_graphic = graphic
169-
if clicked_graphic is not None:
170+
if clicked_graphic != 0:
170171
self.clicked_graphic = clicked_graphic
171-
if disabled_graphic is not None:
172+
if disabled_graphic != 0:
172173
self.disabled_graphic = disabled_graphic
173174

174-
if label is not None:
175+
if label != 0:
175176
self.label = label
176177

177178
self.draw(self.graphwin)

goopylib/objects/CycleButton.py

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,20 @@ def __init__(self, *states, state=0, disabled_graphic=None, autoflush=True, laye
1717

1818
self.graphic = states[state]
1919

20+
self.number_of_states = len(self.states)
21+
22+
number_of_states = 0
23+
self.anchor = [0, 0]
24+
for state in self.states:
25+
state_anchor = state.get_anchor()
26+
if state_anchor is not None:
27+
self.anchor[0] += state_anchor[0]
28+
self.anchor[1] += state_anchor[1]
29+
number_of_states += 1
30+
31+
if number_of_states != 0:
32+
self.anchor = [self.anchor[0] // number_of_states, self.anchor[1] // number_of_states]
33+
2034
GraphicsObject.__init__(self, (), tag=tag, bounds=bounds)
2135
GraphicsObject.cyclebutton_instances.add(self)
2236

@@ -30,6 +44,12 @@ def __iter__(self):
3044
for state in self.states:
3145
yield state
3246

47+
def __getitem__(self, item):
48+
return self.states[item]
49+
50+
def __len__(self):
51+
return self.number_of_states
52+
3353
def _draw(self, canvas=None, options=None):
3454
self.states[self.state].draw(canvas, _internal_call=True)
3555
self.drawn_graphic = self.states[self.state]
@@ -75,6 +95,8 @@ def _rotate(self, dr, sampling="bicubic", center=None):
7595
self.disabled_graphic.rotate(dr, sampling=sampling, center=center)
7696

7797
def _move(self, dx, dy):
98+
self.anchor[0] += dx
99+
self.anchor[1] += dy
78100
for graphic in self.states:
79101
graphic.move(dx, dy)
80102
if self.disabled_graphic is not None:
@@ -227,16 +249,47 @@ def set_state(self, state):
227249

228250
def add_state(self, state):
229251
self.states.append(state)
252+
self.number_of_states += 1
253+
number_of_states = 0
254+
self.anchor = [0, 0]
255+
for state in self.states:
256+
state_anchor = state.get_anchor()
257+
if state_anchor is not None:
258+
self.anchor[0] += state_anchor[0]
259+
self.anchor[1] += state_anchor[1]
260+
number_of_states += 1
261+
262+
self.anchor = [self.anchor[0] // number_of_states, self.anchor[1] // number_of_states]
230263
return self
231264

232265
def remove_state(self, state):
233-
if state not in self.states:
234-
raise GraphicsError("\n\nThe state to remove is not an existing state of this cycle button")
266+
self.number_of_states -= 1
267+
number_of_states = 0
268+
self.anchor = [0, 0]
269+
for state in self.states:
270+
state_anchor = state.get_anchor()
271+
if state_anchor is not None:
272+
self.anchor[0] += state_anchor[0]
273+
self.anchor[1] += state_anchor[1]
274+
number_of_states += 1
275+
276+
self.anchor = [self.anchor[0] // number_of_states, self.anchor[1] // number_of_states]
235277

236278
self.states.remove(state)
237279
return self
238280

239281
def pop_state(self, index):
282+
self.number_of_states -= 1
283+
number_of_states = 0
284+
self.anchor = [0, 0]
285+
for state in self.states:
286+
state_anchor = state.get_anchor()
287+
if state_anchor is not None:
288+
self.anchor[0] += state_anchor[0]
289+
self.anchor[1] += state_anchor[1]
290+
number_of_states += 1
291+
292+
self.anchor = [self.anchor[0] // number_of_states, self.anchor[1] // number_of_states]
240293
return self.states.pop(index)
241294

242295
def set_object(self, obj):
@@ -269,7 +322,7 @@ def get_object(self):
269322
# GETTER FUNCTIONS
270323

271324
def get_anchor(self):
272-
return self.graphic.anchor
325+
return self.graphic.get_anchor()
273326

274327
def get_state(self):
275328
return self.state

goopylib/objects/Entry.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,30 @@ def allow_character(self, character):
202202
return self
203203

204204
def allow_only_numeric(self, allow=True):
205+
if allow:
206+
self.allowed_symbols = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', "-", "."]
207+
else:
208+
self.allowed_symbols = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
209+
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
210+
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
211+
'Z', '!', '"', '#', '$', '%', '&', '\\', "'", '(', ')', '*', '+', ',', '-', '.',
212+
'/', ':', ';', '<', '=', '>', '?', '@', '[', '\'', '"', ']', '^', '_', '`', '{',
213+
'|', '}', '~', ':', " "]
214+
return self
215+
216+
def allow_only_integers(self, allow=True):
217+
if allow:
218+
self.allowed_symbols = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', "-"]
219+
else:
220+
self.allowed_symbols = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
221+
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
222+
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
223+
'Z', '!', '"', '#', '$', '%', '&', '\\', "'", '(', ')', '*', '+', ',', '-', '.',
224+
'/', ':', ';', '<', '=', '>', '?', '@', '[', '\'', '"', ']', '^', '_', '`', '{',
225+
'|', '}', '~', ':', " "]
226+
return self
227+
228+
def allow_only_positive_integers(self, allow=True):
205229
if allow:
206230
self.allowed_symbols = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
207231
else:

goopylib/objects/GraphicsObject.py

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,10 @@ def animate_blinking(self, interval, animate=True, blink_graphic=None, number_of
10391039
# Object Gliding Functions
10401040
def glide(self, dx, dy, time=1, easing_x=py_ease_linear(), easing_y=None, allow_duplicate=True,
10411041
duplicates_metric=("Time", "Initial", "Change")):
1042+
1043+
if self.get_anchor() is None:
1044+
raise GraphicsError("\n\nGraphicsError: gliding functions unsupported for this object")
1045+
10421046
for metric in duplicates_metric:
10431047
if metric not in DUPLICATES_METRICS["2D Animation"]:
10441048
raise GraphicsError("\n\nGraphicsError: Metric in duplicates_metric must be one of "
@@ -1066,7 +1070,9 @@ def glide(self, dx, dy, time=1, easing_x=py_ease_linear(), easing_y=None, allow_
10661070
f"(integer or float), not {time}")
10671071

10681072
if len(self.animation_queues["glide"]) > 0:
1069-
initial = self.animation_queues["glide"][-1]["Initial"] + self.animation_queues["glide"][-1]["Change"]
1073+
initial = [
1074+
self.animation_queues["glide"][-1]["Initial"][0] + self.animation_queues["glide"][-1]["Change"][0],
1075+
self.animation_queues["glide"][-1]["Initial"][1] + self.animation_queues["glide"][-1]["Change"][1]]
10701076
start = self.animation_queues["glide"][-1]["Start"] + self.animation_queues["glide"][-1]["Time"]
10711077
else:
10721078
initial = self.anchor.copy()
@@ -1090,6 +1096,9 @@ def glide(self, dx, dy, time=1, easing_x=py_ease_linear(), easing_y=None, allow_
10901096
def glide_x(self, dx, time=1, easing=py_ease_linear(), allow_duplicate=True,
10911097
duplicates_metric=("Time", "Initial", "Change")):
10921098

1099+
if self.get_anchor() is None:
1100+
raise GraphicsError("\n\nGraphicsError: gliding functions unsupported for this object")
1101+
10931102
for metric in duplicates_metric:
10941103
if metric not in DUPLICATES_METRICS["1D Animation"]:
10951104
raise GraphicsError("\n\nGraphicsError: Metric in duplicates_metric must be one of "
@@ -1108,7 +1117,9 @@ def glide_x(self, dx, time=1, easing=py_ease_linear(), allow_duplicate=True,
11081117
f"not {allow_duplicate}")
11091118

11101119
if len(self.animation_queues["glide"]) > 0:
1111-
initial = self.animation_queues["glide"][-1]["Initial"] + self.animation_queues["glide"][-1]["Change"]
1120+
initial = [
1121+
self.animation_queues["glide"][-1]["Initial"][0] + self.animation_queues["glide"][-1]["Change"][0],
1122+
self.animation_queues["glide"][-1]["Initial"][1] + self.animation_queues["glide"][-1]["Change"][1]]
11121123
start = self.animation_queues["glide"][-1]["Start"] + self.animation_queues["glide"][-1]["Time"]
11131124
else:
11141125
initial = self.anchor.copy()
@@ -1131,6 +1142,10 @@ def glide_x(self, dx, time=1, easing=py_ease_linear(), allow_duplicate=True,
11311142

11321143
def glide_y(self, dy, time=1, easing=py_ease_linear(), allow_duplicate=True,
11331144
duplicates_metric=("Time", "Initial", "Change")):
1145+
1146+
if self.get_anchor() is None:
1147+
raise GraphicsError("\n\nGraphicsError: gliding functions unsupported for this object")
1148+
11341149
for metric in duplicates_metric:
11351150
if metric not in DUPLICATES_METRICS["1D Animation"]:
11361151
raise GraphicsError("\n\nGraphicsError: Metric in duplicates_metric must be one of "
@@ -1149,7 +1164,9 @@ def glide_y(self, dy, time=1, easing=py_ease_linear(), allow_duplicate=True,
11491164
f"not {allow_duplicate}")
11501165

11511166
if len(self.animation_queues["glide"]) > 0:
1152-
initial = self.animation_queues["glide"][-1]["Initial"] + self.animation_queues["glide"][-1]["Change"]
1167+
initial = [
1168+
self.animation_queues["glide"][-1]["Initial"][0] + self.animation_queues["glide"][-1]["Change"][0],
1169+
self.animation_queues["glide"][-1]["Initial"][1] + self.animation_queues["glide"][-1]["Change"][1]]
11531170
start = self.animation_queues["glide"][-1]["Start"] + self.animation_queues["glide"][-1]["Time"]
11541171
else:
11551172
initial = self.anchor.copy()
@@ -1173,6 +1190,9 @@ def glide_y(self, dy, time=1, easing=py_ease_linear(), allow_duplicate=True,
11731190
def glide_to(self, x, y, time=1, easing_x=py_ease_linear(), easing_y=None, allow_duplicate=True,
11741191
duplicates_metric=("Time", "Final")):
11751192

1193+
if self.get_anchor() is None:
1194+
raise GraphicsError("\n\nGraphicsError: gliding functions unsupported for this object")
1195+
11761196
for metric in duplicates_metric:
11771197
if metric not in DUPLICATES_METRICS["2D Animation"]:
11781198
raise GraphicsError("\n\nGraphicsError: Metric in duplicates_metric must be one of "
@@ -1200,7 +1220,9 @@ def glide_to(self, x, y, time=1, easing_x=py_ease_linear(), easing_y=None, allow
12001220
f"(integer or float), not {time}")
12011221

12021222
if len(self.animation_queues["glide"]) > 0:
1203-
initial = self.animation_queues["glide"][-1]["Initial"] + self.animation_queues["glide"][-1]["Change"]
1223+
initial = [
1224+
self.animation_queues["glide"][-1]["Initial"][0] + self.animation_queues["glide"][-1]["Change"][0],
1225+
self.animation_queues["glide"][-1]["Initial"][1] + self.animation_queues["glide"][-1]["Change"][1]]
12041226
start = self.animation_queues["glide"][-1]["Start"] + self.animation_queues["glide"][-1]["Time"]
12051227
else:
12061228
initial = self.anchor.copy()
@@ -1223,6 +1245,9 @@ def glide_to(self, x, y, time=1, easing_x=py_ease_linear(), easing_y=None, allow
12231245
return self
12241246

12251247
def glide_to_x(self, x, time=1, easing=py_ease_linear(), allow_duplicate=True, duplicates_metric=("Time", "Final")):
1248+
if self.get_anchor() is None:
1249+
raise GraphicsError("\n\nGraphicsError: gliding functions unsupported for this object")
1250+
12261251
for metric in duplicates_metric:
12271252
if metric not in DUPLICATES_METRICS["1D Animation"]:
12281253
raise GraphicsError("\n\nGraphicsError: Metric in duplicates_metric must be one of "
@@ -1241,7 +1266,9 @@ def glide_to_x(self, x, time=1, easing=py_ease_linear(), allow_duplicate=True, d
12411266
f"not {allow_duplicate}")
12421267

12431268
if len(self.animation_queues["glide"]) > 0:
1244-
initial = self.animation_queues["glide"][-1]["Initial"] + self.animation_queues["glide"][-1]["Change"]
1269+
initial = [
1270+
self.animation_queues["glide"][-1]["Initial"][0] + self.animation_queues["glide"][-1]["Change"][0],
1271+
self.animation_queues["glide"][-1]["Initial"][1] + self.animation_queues["glide"][-1]["Change"][1]]
12451272
start = self.animation_queues["glide"][-1]["Start"] + self.animation_queues["glide"][-1]["Time"]
12461273
else:
12471274
initial = self.anchor.copy()
@@ -1263,6 +1290,9 @@ def glide_to_x(self, x, time=1, easing=py_ease_linear(), allow_duplicate=True, d
12631290
return self
12641291

12651292
def glide_to_y(self, y, time=1, easing=py_ease_linear(), allow_duplicate=True, duplicates_metric=("Time", "Final")):
1293+
if self.get_anchor() is None:
1294+
raise GraphicsError("\n\nGraphicsError: gliding functions unsupported for this object")
1295+
12661296
for metric in duplicates_metric:
12671297
if metric not in DUPLICATES_METRICS["1D Animation"]:
12681298
raise GraphicsError("\n\nGraphicsError: Metric in duplicates_metric must be one of "
@@ -1281,7 +1311,8 @@ def glide_to_y(self, y, time=1, easing=py_ease_linear(), allow_duplicate=True, d
12811311
f"not {allow_duplicate}")
12821312

12831313
if len(self.animation_queues["glide"]) > 0:
1284-
initial = self.animation_queues["glide"][-1]["Initial"] + self.animation_queues["glide"][-1]["Change"]
1314+
initial = [self.animation_queues["glide"][-1]["Initial"][0] + self.animation_queues["glide"][-1]["Change"][0],
1315+
self.animation_queues["glide"][-1]["Initial"][1] + self.animation_queues["glide"][-1]["Change"][1]]
12851316
start = self.animation_queues["glide"][-1]["Start"] + self.animation_queues["glide"][-1]["Time"]
12861317
else:
12871318
initial = self.anchor.copy()
@@ -1988,7 +2019,10 @@ def is_selected(self):
19882019
return selected or self.selected_clicks == self.graphwin.total_left_mouse_clicks
19892020

19902021
def is_clicked(self, mouse_pos):
1991-
return False
2022+
if self.bounds is None:
2023+
return False
2024+
else:
2025+
return self.bounds.is_clicked(mouse_pos)
19922026

19932027
# -------------------------------------------------------------------------
19942028
# STATIC METHODS

goopylib/objects/Image.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,13 @@ def is_clicked(self, mouse_pos):
141141
else:
142142
if self.bounds is None:
143143
if self.drawn:
144-
width, height = abs(self.img.width() * self.graphwin.trans.x_scale), \
145-
abs(self.img.height() * self.graphwin.trans.y_scale)
144+
width, height = abs(self.img.width() * self.graphwin.trans.x_scale) // 2, \
145+
abs(self.img.height() * self.graphwin.trans.y_scale) // 2
146146
else:
147-
width, height = self.img.width(), self.img.height()
147+
width, height = self.img.width() // 2, self.img.height() // 2
148148

149-
if (self.anchor[0] - width / 2 < mouse_pos[0] < self.anchor[0] + width / 2) and (
150-
self.anchor[1] - height / 2 < mouse_pos[1] < self.anchor[1] + height / 2):
149+
if (self.anchor[0] - width < mouse_pos[0] < self.anchor[0] + width) and (
150+
self.anchor[1] - height < mouse_pos[1] < self.anchor[1] + height):
151151
return True
152152
else:
153153
return False

0 commit comments

Comments
 (0)