e2D 1.4.19__py3-none-any.whl → 1.4.20__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.
e2D/__init__.py CHANGED
@@ -10,6 +10,7 @@ PI_QUARTER = PI/4
10
10
  PI_DOUBLE = PI*2
11
11
 
12
12
  sign = lambda val: -1 if val < 0 else (1 if val > 0 else 0)
13
+ clamp = lambda x, minn, maxx: x if x > minn and x < maxx else (minn if x < minn else maxx)
13
14
 
14
15
  class Vector2D:
15
16
  round_values_on_print = 2
@@ -42,6 +43,13 @@ class Vector2D:
42
43
  @property
43
44
  def sign(self) -> "Vector2D":
44
45
  return Vector2D(sign(self.x), sign(self.y))
46
+
47
+ def clamp(self, min_val: Vector2D, max_val: Vector2D) -> "Vector2D":
48
+ return Vector2D(clamp(self.x, min_val.x, max_val.x), clamp(self.y, min_val.y, max_val.y))
49
+
50
+ def iclamp(self, min_val: Vector2D, max_val: Vector2D) -> None:
51
+ self.x = clamp(self.x, min_val.x, max_val.x)
52
+ self.y = clamp(self.y, min_val.y, max_val.y)
45
53
 
46
54
  @property
47
55
  def normalize(self) -> "Vector2D":
e2D/__init__.pyi CHANGED
@@ -12,6 +12,7 @@ PI_DOUBLE : float
12
12
  #
13
13
 
14
14
  sign : Callable[[int|float], Literal[-1,0,1]]
15
+ clamp: Callable[[int|float, int|float, int|float], int|float]
15
16
 
16
17
  class Vector2D:
17
18
  round_values_on_print : int|float
@@ -211,6 +212,54 @@ class Vector2D:
211
212
  """
212
213
  ...
213
214
 
215
+ def clamp(self, min_val: Vector2D, max_val: Vector2D) -> "Vector2D":
216
+ """
217
+ # Clamp the vector's components between the corresponding components of two other vectors.
218
+
219
+ ## Parameters:
220
+ min_val (Vector2D): The minimum vector for clamping.
221
+ max_val (Vector2D): The maximum vector for clamping.
222
+
223
+ ## Returns:
224
+ Vector2D: A new vector with its components clamped between the corresponding components of `min_val` and `max_val`.
225
+
226
+ ## Example:
227
+ v = Vector2D(5, 10)
228
+ min_val = Vector2D(0, 8)
229
+ max_val = Vector2D(6, 12)
230
+ clamped_v = v.clamp(min_val, max_val)
231
+ print(clamped_v) # Output: (5, 10)
232
+
233
+ ## Explanation:
234
+ This method clamps the x and y components of the current vector between the corresponding x and y components
235
+ of the `min_val` and `max_val` vectors. The resulting vector is returned as a new Vector2D instance.
236
+ """
237
+ ...
238
+
239
+ def iclamp(self, min_val: Vector2D, max_val: Vector2D) -> None:
240
+ """
241
+ # Clamp the vector's components in place between the corresponding components of two other vectors.
242
+
243
+ ## Parameters:
244
+ min_val (Vector2D): The minimum vector for clamping.
245
+ max_val (Vector2D): The maximum vector for clamping.
246
+
247
+ ## Returns:
248
+ None
249
+
250
+ ## Example:
251
+ v = Vector2D(5, 10)
252
+ min_val = Vector2D(0, 8)
253
+ max_val = Vector2D(6, 12)
254
+ v.iclamp(min_val, max_val)
255
+ print(v) # Output: (5, 10)
256
+
257
+ ## Explanation:
258
+ This method clamps the x and y components of the current vector in place between the corresponding x and y components
259
+ of the `min_val` and `max_val` vectors. The method modifies the current vector directly.
260
+ """
261
+ ...
262
+
214
263
  @property
215
264
  def normalize(self:"Vector2D") -> "Vector2D":
216
265
  """
e2D/colors.py CHANGED
@@ -82,6 +82,12 @@ __conversion_table__ :dict[__LITERAL_COLOR_MODES__, dict[__LITERAL_COLOR_MODES__
82
82
  },
83
83
  }
84
84
 
85
+ def pygamize_color(color: "__color_pygame__|Color") -> "__color_pygame__":
86
+ return color() if isinstance(color, Color) else color
87
+
88
+ def unpygamize_color(color: "__color_pygame__|Color") -> "Color":
89
+ return Color(*color[:], mode=RGBA_COLOR_MODE) if isinstance(color, __color_pygame__) else color
90
+
85
91
  class Color:
86
92
  def __init__(self, *values, mode:__LITERAL_COLOR_MODES__=RGB_COLOR_MODE) -> None:
87
93
  self.__dict__ = dict(zip(mode, values))
@@ -179,7 +185,7 @@ class Color:
179
185
  return "Color(" + ", ".join(f"{k}:{v}" for k, v in self.items) + ")"
180
186
 
181
187
  def __call__(self) -> __color_pygame__:
182
- return __color_pygame__(int(self.r), int(self.g), int(self.b))
188
+ return __color_pygame__(int(self.r), int(self.g), int(self.b)) if self.mode == RGB_COLOR_MODE else __color_pygame__(int(self.r), int(self.g), int(self.b), int(self.a))
183
189
 
184
190
  # fast operations Vector2D.operation(both,x,y)
185
191
  def add(self, all3=.0, r=.0, g=.0, b=.0) -> "Color":
@@ -408,6 +414,8 @@ class Color:
408
414
  except:
409
415
  raise TypeError(f"The value {other} of type {type(other)} is not a num type: [{int|float}] nor an array type: [{list|tuple}]")
410
416
 
417
+ @classmethod
418
+ def transparent(cls) -> "Color": return Color(0,0,0,0, mode=RGBA_COLOR_MODE)
411
419
  @classmethod
412
420
  def white(cls) -> "Color": return Color(255,255,255)
413
421
  @classmethod
@@ -427,12 +435,14 @@ class Color:
427
435
  return Color(__randint__(0,255), __randint__(0,255), __randint__(0,255))
428
436
 
429
437
 
438
+ TRANSPARENT_COLOR = Color.transparent()
430
439
  WHITE_COLOR = Color.white()
431
440
  BLACK_COLOR = Color.black()
432
441
  RED_COLOR = Color.red()
433
442
  GREEN_COLOR = Color.green()
434
443
  BLUE_COLOR = Color.blue()
435
444
 
445
+ TRANSPARENT_COLOR_PYG = TRANSPARENT_COLOR()
436
446
  WHITE_COLOR_PYG = WHITE_COLOR()
437
447
  BLACK_COLOR_PYG = BLACK_COLOR()
438
448
  RED_COLOR_PYG = RED_COLOR()
e2D/envs.py CHANGED
@@ -59,12 +59,21 @@ class RootEnv:
59
59
  self.current_frame = 0
60
60
  self.show_fps = show_fps
61
61
  self.events :list[pg.event.Event]= []
62
- self.background_color = BLACK_COLOR_PYG
62
+
63
+ self.__background_color__ :Color= BLACK_COLOR_PYG
64
+
63
65
  self.clear_screen_each_frame = clear_screen_each_frame
64
66
  self.utils :dict[int|str, Util]= {}
65
67
  self.selected_util :Util|None = None
66
68
  self.__quit_on_key_pressed__ = quit_on_key_pressed
67
69
 
70
+ @property
71
+ def background_color(self) -> Color:
72
+ return unpygamize_color(self.__background_color__)
73
+ @background_color.setter
74
+ def background_color(self, color: Color|pg.Color) -> None:
75
+ self.__background_color__ = pygamize_color(color)
76
+
68
77
  @property
69
78
  def screen_size(self) -> Vector2D:
70
79
  return self.__screen_size__
@@ -96,6 +105,8 @@ class RootEnv:
96
105
  for util in utils:
97
106
  if util.surface == None: util.surface = self.screen
98
107
  util.rootEnv = self
108
+ util.id = self.__new_util_id__()
109
+ util.render()
99
110
  self.utils[util.id] = util
100
111
 
101
112
  def remove_utils(self, *utils:int|str|Util) -> None:
@@ -106,6 +117,18 @@ class RootEnv:
106
117
  del self.utils[uid.id]
107
118
  else:
108
119
  raise Exception(f"Unknown util type: {uid}")
120
+
121
+ def __new_util_id__(self) -> int:
122
+ if not self.utils: return 0
123
+ else: return max(self.utils.keys()) + 1
124
+
125
+ def get_util(self, uid:int|str) -> Util|None:
126
+ if isinstance(uid, Util):
127
+ return self.utils.get(uid.id)
128
+ elif isinstance(uid, int) or isinstance(uid, str):
129
+ return self.utils.get(uid)
130
+ else:
131
+ raise Exception(f"Unknown util type: {uid}")
109
132
 
110
133
  @property
111
134
  def runtime_seconds(self) -> float:
@@ -115,24 +138,25 @@ class RootEnv:
115
138
  self.env = sub_env
116
139
 
117
140
  def clear(self) -> None:
118
- self.screen.fill(self.background_color)
141
+ self.screen.fill(self.__background_color__)
119
142
 
120
143
  def clear_rect(self, position:Vector2D, size:Vector2D) -> None:
121
- self.screen.fill(self.background_color, position() + size())
144
+ self.screen.fill(self.__background_color__, position() + size())
122
145
 
123
146
  def print(self,
124
- text : str,
125
- position : Vector2D,
126
- color : pg.color.Color = WHITE_COLOR_PYG,
127
- pivot_position : __LITERAL_PIVOT_POSITIONS__ = "top_left",
128
- font : pg.font.Font = FONT_ARIAL_32,
129
- bg_color : None|pg.color.Color = None,
130
- border_color : pg.color.Color = WHITE_COLOR_PYG,
131
- border_width : float = 0.0,
132
- border_radius : int|list[int]|tuple[int,int,int,int] = -1,
133
- margin : Vector2D = Vector2D.zero(),
134
- personalized_surface : pg.Surface|None = None
147
+ text : str,
148
+ position : Vector2D,
149
+ color : pg.color.Color = WHITE_COLOR_PYG,
150
+ pivot_position : __LITERAL_PIVOT_POSITIONS__ = "top_left",
151
+ font : pg.font.Font = FONT_ARIAL_32,
152
+ bg_color : None|pg.color.Color = None,
153
+ border_color : pg.color.Color = WHITE_COLOR_PYG,
154
+ border_width : float = 0.0,
155
+ border_radius : int|list[int]|tuple[int,int,int,int] = -1,
156
+ margin : Vector2D = Vector2D.zero(),
157
+ personalized_surface : pg.Surface|None = None
135
158
  ) -> None:
159
+
136
160
  text_box = font.render(text, True, color)
137
161
  size = Vector2D(*text_box.get_size()) + margin * 2
138
162
  pivotted_position = position - size * __PIVOT_POSITIONS_MULTIPLIER__[pivot_position] + margin
e2D/utils.py CHANGED
@@ -96,78 +96,114 @@ class Keyboard:
96
96
  class Util:
97
97
  def __init__(self) -> None:
98
98
  self.rootEnv = None
99
- self.surface : pg.Surface
99
+ self.surface : pg.Surface = pg.SurfaceType
100
100
  self.id : int|str
101
101
  self.is_hovered :bool= False
102
+ self.hidden :bool= False
103
+ def hide(self) -> None:
104
+ self.hidden = True
105
+ def show(self) -> None:
106
+ self.hidden = False
107
+ def render(self) -> None: pass
102
108
  def draw(self) -> None: pass
103
109
  def update(self) -> None: pass
104
110
 
105
111
  class InputCell(Util):
106
112
  def __init__(self,
107
- id : int|str,
108
- initial_value : str,
109
- position : Vector2D,
110
- size : Vector2D,
111
- prefix : str|None = None,
112
- text_color : Color = Color.white(),
113
- bg_color : None|Color = None,
114
- border_color : Color = Color.white(),
115
- border_width : float = 0,
116
- border_radius : int|list[int]|tuple[int,int,int,int] = -1,
117
- margin : Vector2D = Vector2D.zero(),
118
- pivot_position : __LITERAL_PIVOT_POSITIONS__ = "center_center",
119
- font : pg.font.Font = FONT_ARIAL_32,
120
- personalized_surface : pg.Surface|None = None,
121
- on_enter_pressed : Callable[[str], Any] = lambda full_text: ...,
122
- check_when_adding : Callable[[str], str] = lambda new_text: new_text
113
+ initial_value : str,
114
+ position : Vector2D,
115
+ size : Vector2D,
116
+ prefix : str|None = None,
117
+ text_color : Color|pg.Color = Color.white(),
118
+ bg_color : None|Color|pg.Color = None,
119
+ border_color : Color|pg.Color = Color.white(),
120
+ border_width : float = 0,
121
+ border_radius : int|list[int]|tuple[int,int,int,int] = -1,
122
+ margin : Vector2D = Vector2D.zero(),
123
+ pivot_position : __LITERAL_PIVOT_POSITIONS__ = "center_center",
124
+ font : pg.font.Font = FONT_ARIAL_32,
125
+ personalized_surface : pg.Surface|None = None,
126
+ on_enter_pressed : Callable[[str], Any] = lambda full_text: ...,
127
+ check_when_adding : Callable[[str], str] = lambda new_text: new_text,
123
128
  ) -> None:
124
129
  super().__init__()
130
+
131
+ self.value = initial_value
125
132
 
126
- self.id = id
127
- self.on_enter_pressed = on_enter_pressed
128
- self.check_when_adding = check_when_adding
129
- self.prefix = prefix if prefix != None else ""
130
-
131
- self.text_color = text_color
132
- self.font = font
133
- self.surface = personalized_surface
134
- self.bg_color = bg_color
135
133
  # size = Vector2D(*self.text_box.get_size()) + self.margin * 2
136
134
  self.size = size
137
135
  self.position = (position - size * __PIVOT_POSITIONS_MULTIPLIER__[pivot_position] + margin)
136
+
137
+ self.prefix = prefix if prefix != None else ""
138
+
139
+ self.font = font
140
+
138
141
  self.bg_rect = [0, 0] + size()
139
- self.margin_rect = (margin * -1)() + size()
140
- self.border_color = border_color
142
+
141
143
  self.border_radius = [border_radius]*4 if not any(isinstance(border_radius, cls) for cls in {tuple, list}) else border_radius
142
144
  self.border_width = border_width
145
+
146
+ self.margin_rect = (margin * -1)() + size()
143
147
 
144
- self.value = initial_value
148
+ self.on_enter_pressed = on_enter_pressed
149
+ self.check_when_adding = check_when_adding
150
+
145
151
  self.update_text()
146
152
 
153
+ self.surface = personalized_surface
147
154
  self.text_surface = pg.Surface(self.size(), pg.SRCALPHA, 32).convert_alpha()
155
+
156
+ self.text_color = text_color
157
+ self.bg_color = bg_color
158
+ self.border_color = border_color
148
159
 
160
+ @property
161
+ def text_color(self) -> Color:
162
+ return unpygamize_color(self.__text_color__)
163
+ @text_color.setter
164
+ def text_color(self, new_color:Color|pg.Color) -> None:
165
+ self.__text_color__ = pygamize_color(new_color)
166
+ @property
167
+ def bg_color(self) -> Color|None:
168
+ return unpygamize_color(self.__bg_color__) if self.__bg_color__ else None
169
+ @bg_color.setter
170
+ def bg_color(self, new_color:Color|pg.Color|None) -> None:
171
+ self.__bg_color__ = pygamize_color(new_color) if new_color else None
172
+ @property
173
+ def border_color(self) -> Color:
174
+ return unpygamize_color(self.__border_color__)
175
+ @border_color.setter
176
+ def border_color(self, new_color:Color|pg.Color) -> None:
177
+ self.__border_color__ = pygamize_color(new_color)
178
+
149
179
  def draw(self) -> None:
150
- self.text_surface.fill((0,0,0,0))
151
- if self.bg_color != None:
152
- pg.draw.rect(self.text_surface, self.bg_color(), self.bg_rect, 0, -1, *self.border_radius)
180
+ if self.hidden: return
181
+ self.text_surface.fill(TRANSPARENT_COLOR_PYG)
182
+
183
+ if self.__bg_color__ is not None:
184
+ pg.draw.rect(self.text_surface, self.__bg_color__(), self.bg_rect, 0, -1, *self.border_radius)
153
185
 
154
186
  self.text_surface.blit(self.text_box, self.text_position())
155
187
 
156
188
  if self.rootEnv.selected_util != self:
157
189
  if self.border_width:
158
- pg.draw.rect(self.text_surface, self.border_color(), self.margin_rect, self.border_width, -1, *self.border_radius)
190
+ pg.draw.rect(self.text_surface, self.__border_color__(), self.margin_rect, self.border_width, -1, *self.border_radius)
159
191
  else:
160
- pg.draw.rect(self.text_surface, [127 + 127 * _mt.sin(self.rootEnv.runtime_seconds * 10)]*3, self.margin_rect, self.border_width if self.border_width else 10, -1, *self.border_radius)
192
+ k = 127.5 + 127.5 * _mt.sin(self.rootEnv.runtime_seconds * 10)
193
+ pg.draw.rect(self.text_surface, pg.Color(k, k, k), self.margin_rect, self.border_width if self.border_width else 10, -1, *self.border_radius)
161
194
 
162
195
  self.surface.blit(self.text_surface, self.position())
163
196
 
164
197
  def update(self) -> None:
198
+ if self.hidden: return
165
199
  self.is_hovered = self.position.x < self.rootEnv.mouse.position.x < self.position.x + self.size.x and\
166
200
  self.position.y < self.rootEnv.mouse.position.y < self.position.y + self.size.y
201
+
167
202
  if self.rootEnv.mouse.get_key(0, "just_pressed"):
168
203
  if self.is_hovered:
169
204
  self.rootEnv.selected_util = self if self.rootEnv.selected_util != self else None
170
205
  self.update_text()
206
+
171
207
  if self.rootEnv.selected_util == self:
172
208
  for event in self.rootEnv.events:
173
209
  if event.type == pg.TEXTINPUT:
@@ -183,9 +219,327 @@ class InputCell(Util):
183
219
  self.update_text()
184
220
 
185
221
  def update_text(self) -> None:
186
- self.text_box = self.font.render(self.prefix + self.value, True, self.text_color())
222
+ self.text_box = self.font.render(self.prefix + self.value, True, self.__text_color__())
187
223
  if self.rootEnv != None and self.rootEnv.selected_util == self:
188
224
  # self.text_position = self.position + self.size * Vector2D(.85, .5) - Vector2D(*self.text_box.get_size()) * Vector2D(1, .5) - self.position
189
225
  self.text_position = self.position + self.size * .5 - Vector2D(*self.text_box.get_size()) * Vector2D(.5, .5) - self.position
190
226
  else:
191
227
  self.text_position = self.position + self.size * .5 - Vector2D(*self.text_box.get_size()) * Vector2D(.5, .5) - self.position
228
+
229
+ class Slider(Util):
230
+ def __init__(self,
231
+ text : str,
232
+ position : Vector2D,
233
+ size : Vector2D,
234
+ min_value : float = 0,
235
+ max_value : float = 100,
236
+ step : float = 1,
237
+ color : Color|pg.Color = Color(200, 200, 200),
238
+ handleColour : Color|pg.Color = Color.white(),
239
+ initial_value : float = 0,
240
+ rounded : bool = True,
241
+ handleRadius : float = 10,
242
+ text_offset : V2 = V2(1.1, .5),
243
+ text_pivot : __LITERAL_PIVOT_POSITIONS__ = "center_center",
244
+ personalized_surface : pg.Surface|None = None,
245
+ ) -> None:
246
+ super().__init__()
247
+
248
+ self.text = text
249
+ self.selected = False
250
+ self.min = min_value
251
+ self.max = max_value
252
+ self.step = step
253
+
254
+ self.position = position
255
+ self.size = size
256
+
257
+ self.value = clamp(initial_value, self.min, self.max)
258
+
259
+ self.radius = self.size.y // 2 if rounded else 0
260
+ self.text_offset = text_offset
261
+ self.text_pivot = text_pivot
262
+
263
+ self.handleRadius = handleRadius
264
+ self.surface = personalized_surface
265
+
266
+ self.hidden = False
267
+
268
+ self.color = color
269
+ self.handleColour = handleColour
270
+
271
+ @property
272
+ def color(self) -> Color:
273
+ return unpygamize_color(self.__color__)
274
+ @color.setter
275
+ def color(self, new_color:Color|pg.Color) -> None:
276
+ self.__color__ = pygamize_color(new_color)
277
+ @property
278
+ def handleColour(self) -> Color:
279
+ return unpygamize_color(self.__handleColour__)
280
+ @handleColour.setter
281
+ def handleColour(self, new_color:Color|pg.Color) -> None:
282
+ self.__handleColour__ = pygamize_color(new_color)
283
+
284
+ def draw(self) -> None:
285
+ if self.hidden: return
286
+ pg.draw.rect(self.rootEnv.screen, self.__color__, self.position() + self.size())
287
+
288
+ if self.radius:
289
+ pg.draw.circle(self.rootEnv.screen, self.__color__, (self.position.x, self.position.y + self.size.y // 2), self.radius)
290
+ pg.draw.circle(self.rootEnv.screen, self.__color__, (self.position.x + self.size.x, self.position.y + self.size.y // 2), self.radius)
291
+
292
+ circle = V2(int(self.position.x + (self.value - self.min) / (self.max - self.min) * self.size.x), self.position.y + self.size.y // 2)
293
+
294
+ pg.draw.circle(self.rootEnv.screen, self.__color__, circle(), self.handleRadius * 1.25)
295
+ pg.draw.circle(self.rootEnv.screen, self.__handleColour__, circle(), self.handleRadius)
296
+ self.rootEnv.print(self.text.format(round(self.value, 2)), self.position + self.size * self.text_offset, pivot_position=self.text_pivot)
297
+
298
+ def update(self) -> None:
299
+ if self.hidden: return
300
+ x,y = self.rootEnv.mouse.position
301
+
302
+ if self.rootEnv.mouse.get_key(0, "just_pressed") and self.__contains__(x, y):
303
+ self.rootEnv.selected_util = self
304
+ elif self.rootEnv.mouse.get_key(0, "just_released"):
305
+ self.rootEnv.selected_util = None
306
+
307
+ if self.rootEnv.selected_util == self:
308
+ new_value = (x - self.position.x) / self.size.x * self.max + self.min
309
+ self.value = clamp(new_value, self.min, self.max)
310
+
311
+ def __contains__(self, x, y) -> bool:
312
+ handleX = self.position.x + (self.value - self.min) / (self.max - self.min) * self.size.x
313
+ handleY = self.position.y + self.size.y // 2
314
+ return (handleX - x) ** 2 + (handleY - y) ** 2 <= self.handleRadius ** 2
315
+
316
+ def setValue(self, value) -> None:
317
+ self.value = clamp(value, self.min, self.max)
318
+
319
+ def getValue(self) -> float:
320
+ return self.value
321
+
322
+ class Button(Util):
323
+ def __init__(self,
324
+ text : str,
325
+ position : V2|Vector2D,
326
+ size : V2|Vector2D,
327
+ callback : Callable[[...], None]|Callable[[], None],
328
+ default_color : Color|pg.Color,
329
+ hovered_color : Color|pg.Color,
330
+ border_color : Color|pg.Color,
331
+ text_color : Color|pg.Color = WHITE_COLOR_PYG,
332
+ font : pg.font.Font = FONT_ARIAL_32,
333
+ border_radius : float = 10,
334
+ border_width : float = 10,
335
+ starting_hiddden : bool = False,
336
+ args : list = [],
337
+ activation_mode : __LITERAL_KEY_MODE_TYPES__ = "just_pressed",
338
+ pivot_position : __LITERAL_PIVOT_POSITIONS__ = "top_left",
339
+ personalized_surface : pg.Surface|None = None,
340
+ ) -> None:
341
+ super().__init__()
342
+
343
+ self.text = text
344
+ self.font = font
345
+
346
+ self.callback = callback
347
+
348
+ self.border_radius = border_radius
349
+ self.__size__ = size
350
+ self.__border_width__ = border_width
351
+
352
+ self.update_position(position, pivot_position)
353
+
354
+ self.hidden = starting_hiddden
355
+ self.args = args
356
+
357
+ self.activation_mode = activation_mode
358
+
359
+ self.hovered = False
360
+
361
+ self.text_color = text_color
362
+ self.default_color = default_color
363
+ self.border_color = border_color
364
+ self.hovered_color = hovered_color
365
+
366
+ self.surface = personalized_surface
367
+ self.update_surface()
368
+
369
+ def update_position(self, new_position:V2, pivot_position:__LITERAL_PIVOT_POSITIONS__="top_left") -> None:
370
+ self.position = new_position - (self.__size__ + self.border_width * 2) * __PIVOT_POSITIONS_MULTIPLIER__[pivot_position]
371
+
372
+ def update_surface(self, render=False) -> None:
373
+ self.buffer_surface = pg.Surface((self.__size__ + self.__border_width__ * 2)(), pg.SRCALPHA, 32).convert_alpha()
374
+ if render: self.render()
375
+
376
+ @property
377
+ def size(self) -> V2:
378
+ return self.__size__
379
+ @size.setter
380
+ def size(self, new_size:V2|Vector2D) -> None:
381
+ self.__size__ = new_size
382
+ self.update_surface(render=True)
383
+
384
+ @property
385
+ def border_width(self) -> float:
386
+ return self.__border_width__
387
+ @border_width.setter
388
+ def border_width(self, new_width:float) -> None:
389
+ self.__border_width__ = new_width
390
+ self.update_surface(render=True)
391
+
392
+ @property
393
+ def text_color(self) -> Color:
394
+ return unpygamize_color(self.__text_color__)
395
+ @text_color.setter
396
+ def text_color(self, new_color:Color|pg.Color) -> None:
397
+ self.__text_color__ = pygamize_color(new_color)
398
+ @property
399
+ def default_color(self) -> Color:
400
+ return unpygamize_color(self.__default_color__)
401
+ @default_color.setter
402
+ def default_color(self, new_color:Color|pg.Color) -> None:
403
+ self.__default_color__ = pygamize_color(new_color)
404
+ @property
405
+ def border_color(self) -> Color:
406
+ return unpygamize_color(self.__border_color__)
407
+ @border_color.setter
408
+ def border_color(self, new_color:Color|pg.Color) -> None:
409
+ self.__border_color__ = pygamize_color(new_color)
410
+ @property
411
+ def hovered_color(self) -> Color:
412
+ return unpygamize_color(self.__hovered_color__)
413
+ @hovered_color.setter
414
+ def hovered_color(self, new_color:Color|pg.Color) -> None:
415
+ self.__hovered_color__ = pygamize_color(new_color)
416
+
417
+ def render(self) -> None:
418
+ print("rendering button")
419
+ self.buffer_surface.fill(TRANSPARENT_COLOR_PYG)
420
+
421
+ color = self.__hovered_color__ if self.hovered else self.__default_color__
422
+ pg.draw.rect(self.buffer_surface, self.__border_color__, V2.zero()() + (self.size + self.border_width * 2)(), border_radius=self.border_radius)
423
+ pg.draw.rect(self.buffer_surface, color, (V2.zero() + self.border_width)() + self.size(), border_radius=self.border_radius)
424
+
425
+ self.rootEnv.print(self.text, self.border_width + self.size * .5, color=self.__text_color__, font=self.font, pivot_position="center_center", personalized_surface=self.buffer_surface)
426
+
427
+ def draw(self) -> None:
428
+ if self.hidden: return
429
+ self.surface.blit(self.buffer_surface, (self.position)())
430
+
431
+ def update(self) -> None:
432
+ if self.hidden: return
433
+
434
+ old_overed = self.hovered
435
+ self.hovered = \
436
+ self.position.x < self.rootEnv.mouse.position.x < self.position.x + self.size.x and \
437
+ self.position.y < self.rootEnv.mouse.position.y < self.position.y + self.size.y
438
+ if self.hovered != old_overed:
439
+ self.render()
440
+
441
+ if self.hovered and self.rootEnv.mouse.get_key(0, self.activation_mode):
442
+ self.callback(*self.args)
443
+ self.rootEnv.selected_util = self
444
+ self.render()
445
+ elif self.rootEnv.selected_util == self:
446
+ self.rootEnv.selected_util = None
447
+ self.render()
448
+
449
+ class Label(Util):
450
+ def __init__(self,
451
+ text : str,
452
+ position : V2|Vector2D,
453
+ size : V2|Vector2D,
454
+ default_color : Color|pg.Color = TRANSPARENT_COLOR_PYG,
455
+ border_color : Color|pg.Color = WHITE_COLOR_PYG,
456
+ text_color : Color|pg.Color = WHITE_COLOR_PYG,
457
+ font : pg.font.Font = FONT_ARIAL_32,
458
+ border_radius : float = 10,
459
+ border_width : float = 10,
460
+ starting_hiddden : bool = False,
461
+ personalized_surface : pg.Surface|None = None,
462
+ pivot_position : __LITERAL_PIVOT_POSITIONS__ = "top_left",
463
+ ) -> None:
464
+ super().__init__()
465
+
466
+ self.__text__ = text
467
+ self.font = font
468
+
469
+ self.border_radius = border_radius
470
+ self.__size__ = size
471
+ self.__border_width__ = border_width
472
+
473
+ self.position = self.update_position(position, pivot_position)
474
+
475
+ self.hidden = starting_hiddden
476
+
477
+ self.text_color = text_color
478
+ self.default_color = default_color
479
+ self.border_color = border_color
480
+
481
+ self.surface = personalized_surface
482
+ self.update_surface()
483
+
484
+ def update_position(self, new_position:V2, pivot_position:__LITERAL_PIVOT_POSITIONS__="top_left") -> None:
485
+ self.position = new_position - (self.__size__ + self.border_width * 2) * __PIVOT_POSITIONS_MULTIPLIER__[pivot_position]
486
+
487
+ def update_surface(self, render=False) -> None:
488
+ self.buffer_surface = pg.Surface((self.__size__ + self.__border_width__ * 2)(), pg.SRCALPHA, 32).convert_alpha()
489
+ if render: self.render()
490
+
491
+ @property
492
+ def text(self) -> str:
493
+ return self.__text__
494
+ @text.setter
495
+ def text(self, new_text:str) -> None:
496
+ self.__text__ = new_text
497
+ self.render()
498
+
499
+ @property
500
+ def size(self) -> V2:
501
+ return self.__size__
502
+ @size.setter
503
+ def size(self, new_size:V2|Vector2D) -> None:
504
+ self.__size__ = new_size
505
+ self.update_surface(render=True)
506
+
507
+ @property
508
+ def border_width(self) -> float:
509
+ return self.__border_width__
510
+ @border_width.setter
511
+ def border_width(self, new_width:float) -> None:
512
+ self.__border_width__ = new_width
513
+ self.update_surface(render=True)
514
+
515
+ @property
516
+ def text_color(self) -> Color:
517
+ return unpygamize_color(self.__text_color__)
518
+ @text_color.setter
519
+ def text_color(self, new_color:Color|pg.Color) -> None:
520
+ self.__text_color__ = pygamize_color(new_color)
521
+ @property
522
+ def default_color(self) -> Color:
523
+ return unpygamize_color(self.__default_color__)
524
+ @default_color.setter
525
+ def default_color(self, new_color:Color|pg.Color) -> None:
526
+ self.__default_color__ = pygamize_color(new_color)
527
+ @property
528
+ def border_color(self) -> Color:
529
+ return unpygamize_color(self.__border_color__)
530
+ @border_color.setter
531
+ def border_color(self, new_color:Color|pg.Color) -> None:
532
+ self.__border_color__ = pygamize_color(new_color)
533
+
534
+ def render(self) -> None:
535
+ print("rendering label")
536
+ self.buffer_surface.fill(TRANSPARENT_COLOR_PYG)
537
+
538
+ pg.draw.rect(self.buffer_surface, self.__border_color__, V2.zero()() + (self.size + self.border_width * 2)(), border_radius=self.border_radius)
539
+ pg.draw.rect(self.buffer_surface, self.__default_color__, (V2.zero() + self.border_width)() + self.size(), border_radius=self.border_radius)
540
+
541
+ self.rootEnv.print(self.text, self.border_width + self.size * .5, color=self.__text_color__, font=self.font, pivot_position="center_center", personalized_surface=self.buffer_surface)
542
+
543
+ def draw(self) -> None:
544
+ if self.hidden: return
545
+ self.surface.blit(self.buffer_surface, (self.position)())
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: e2D
3
- Version: 1.4.19
3
+ Version: 1.4.20
4
4
  Summary: Python library for 2D games. Streamlines dev with keyboard/mouse input, vector calculations, color manipulation, and collision detection. Simplify game creation and unleash creativity!
5
5
  Home-page: https://github.com/marick-py/e2D
6
6
  Author: Riccardo Mariani
@@ -13,6 +13,7 @@ Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
  Requires-Dist: numpy
15
15
  Requires-Dist: pygame
16
+ Dynamic: license-file
16
17
 
17
18
  # e2D
18
19
  ## A Python Game Development Library
@@ -0,0 +1,13 @@
1
+ e2D/__init__.py,sha256=7UmgGI4WotqPLGXyGlNzddUdd5eK1VWqsb2BMAOA78g,22522
2
+ e2D/__init__.pyi,sha256=ckPL2_iz5439-lD-wRLF7t54b_ndF4LT_A24_oyCCTU,45403
3
+ e2D/colors.py,sha256=SwO52zowBs9l_VK1TjyT2GK1Npn5UAsHdCxz3lvaSKQ,18011
4
+ e2D/def_colors.py,sha256=3sJq2L6qFZ3svn2qEWIx0SinNXjb9huNaFigDeJipm8,43805
5
+ e2D/envs.py,sha256=1QnOEI2lCO3B6_EkIBBqgaXfPYLFE_u0_H6AwmZ1R9U,7171
6
+ e2D/plots.py,sha256=_d72ZJo-GIhcJ44XCphFH288cf_ZSwWcbLh_olgGjBc,35880
7
+ e2D/utils.py,sha256=42anOSUxvQ9SOof26VkJPsm6vN9AvckeW0U0RILzi8w,27843
8
+ e2D/winrec.py,sha256=EFFfWYbk27NhS-rWD-BLChXvLjFW1uYZ5LkRGMj_Xo0,1116
9
+ e2d-1.4.20.dist-info/licenses/LICENSE,sha256=hbjljn38VVW9en51B0qzRK-v2FBDijqRWbZIVTk7ipU,1094
10
+ e2d-1.4.20.dist-info/METADATA,sha256=YOwcgB_fj4q1bHxAbh1uK-qcFEWAK8qoA4lZ4-dOFZI,9634
11
+ e2d-1.4.20.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
12
+ e2d-1.4.20.dist-info/top_level.txt,sha256=3vKZ-CGzNlTCpzVMmM0Ht76krCofKw7hZ0wBf-dnKdM,4
13
+ e2d-1.4.20.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.2)
2
+ Generator: setuptools (80.3.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Riccardo Mariani
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Riccardo Mariani
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,13 +0,0 @@
1
- e2D/__init__.py,sha256=Ex3kVbhzHPqoeGhVJr83TAlwRfA65iaoaA_wuKaq1bs,22080
2
- e2D/__init__.pyi,sha256=SgTFu2fx0qOAp8BbiCT8kd6ySzKwjpZqhfcPlE_pTEE,43472
3
- e2D/colors.py,sha256=DgkgUdaQY41nA0VlJaMaT6VZwypG--Cw3Pwakf4OVHM,17412
4
- e2D/def_colors.py,sha256=3sJq2L6qFZ3svn2qEWIx0SinNXjb9huNaFigDeJipm8,43805
5
- e2D/envs.py,sha256=VmXKHcMBPHArx9u15mZtbAb7eXWdmhSC2nz4y_sRvro,6349
6
- e2D/plots.py,sha256=_d72ZJo-GIhcJ44XCphFH288cf_ZSwWcbLh_olgGjBc,35880
7
- e2D/utils.py,sha256=cJarYc6OTIdud7AJZHxwOhxMcEJLlgfKu60kkBu4hB8,14116
8
- e2D/winrec.py,sha256=EFFfWYbk27NhS-rWD-BLChXvLjFW1uYZ5LkRGMj_Xo0,1116
9
- e2d-1.4.19.dist-info/LICENSE,sha256=VP36drkzlpF7Kc7qhWiQ-Foke1Ru3WO0e5JgASurHNM,1073
10
- e2d-1.4.19.dist-info/METADATA,sha256=4Rg4PBPfe_WOlzDT0CPT5450sjo5MX8oIECWWcNy4TQ,9611
11
- e2d-1.4.19.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
12
- e2d-1.4.19.dist-info/top_level.txt,sha256=3vKZ-CGzNlTCpzVMmM0Ht76krCofKw7hZ0wBf-dnKdM,4
13
- e2d-1.4.19.dist-info/RECORD,,