e2D 1.4.20__py3-none-any.whl → 1.4.24__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/envs.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from __future__ import annotations
2
- from typing import Literal
2
+ from typing import Literal, Optional
3
3
 
4
4
  from .utils import *
5
5
  import pygame as pg
@@ -42,13 +42,15 @@ class RootEnv:
42
42
  quit_on_key_pressed : None|int = pg.K_x,
43
43
  vsync : bool = True,
44
44
  window_flags : int = pg.DOUBLEBUF,
45
+ display_index : int = 0,
45
46
  clear_screen_each_frame : bool = True) -> None:
46
47
  self.quit = False
47
48
  self.__screen_size__ :Vector2D= screen_size
48
49
 
49
50
  self.__vsync__ = vsync
50
51
  self.__flags__ = window_flags
51
- self.screen = pg.display.set_mode(self.__screen_size__(), vsync=self.__vsync__, flags=self.__flags__)
52
+ self.__display_index__ = display_index
53
+ self.screen = pg.display.set_mode(self.__screen_size__(), vsync=self.__vsync__, flags=self.__flags__, display=self.__display_index__)
52
54
 
53
55
  self.clock = pg.time.Clock()
54
56
  self.keyboard = Keyboard()
@@ -56,17 +58,31 @@ class RootEnv:
56
58
 
57
59
  self.target_fps = target_fps
58
60
  self.current_fps = self.target_fps if self.target_fps != 0 else 1
61
+ self.__dt__ = 1 / self.current_fps
59
62
  self.current_frame = 0
60
63
  self.show_fps = show_fps
61
64
  self.events :list[pg.event.Event]= []
62
65
 
63
- self.__background_color__ :Color= BLACK_COLOR_PYG
66
+ # Track start time for accurate runtime calculation (excluding compilation time)
67
+ self.set_starting_timer()
68
+
69
+ self.__background_color__ :pg.Color= BLACK_COLOR_PYG
64
70
 
65
71
  self.clear_screen_each_frame = clear_screen_each_frame
66
72
  self.utils :dict[int|str, Util]= {}
67
73
  self.selected_util :Util|None = None
68
74
  self.__quit_on_key_pressed__ = quit_on_key_pressed
69
75
 
76
+ self.fps_label = Label(str(round(self.current_fps,2)), self.screen_size * .01, V2(250, 50), BLACK_COLOR_PYG, TRANSPARENT_COLOR_PYG, WHITE_COLOR_PYG, border_width=0, starting_hidden=(not self.show_fps), pivot_position="top_left", font=FONT_ARIAL_32)
77
+ self.add_utils(self.fps_label)
78
+
79
+ def set_starting_timer(self) -> None:
80
+ self.__start_time__ = pg.time.get_ticks()
81
+
82
+ def init_rec(self, fps:int=30, draw_on_screen:bool=True, path:str='output.mp4', font:pg.font.Font=FONT_MONOSPACE_16) -> None:
83
+ from .winrec import WinRec
84
+ self.__winrecorder__ = WinRec(self, fps=fps, draw_on_screen=draw_on_screen, path=path, font=font)
85
+
70
86
  @property
71
87
  def background_color(self) -> Color:
72
88
  return unpygamize_color(self.__background_color__)
@@ -81,46 +97,51 @@ class RootEnv:
81
97
  @screen_size.setter
82
98
  def screen_size(self, new_size:Vector2D) -> None:
83
99
  self.__screen_size__ = new_size
84
- self.screen = pg.display.set_mode(self.__screen_size__(), vsync=self.__vsync__, flags=self.__flags__)
100
+ self.screen = pg.display.set_mode(self.__screen_size__(), vsync=self.__vsync__, flags=self.__flags__, display=self.__display_index__)
101
+
102
+ def update_screen_to_new_size(self) -> None:
103
+ self.screen = pg.display.set_mode(self.__screen_size__(), vsync=self.__vsync__, flags=self.__flags__, display=self.__display_index__)
85
104
 
86
105
  @property
87
- def delta(self) -> int:
88
- return self.clock.get_time() / 1000
106
+ def delta(self) -> float:
107
+ return self.__dt__
89
108
 
90
109
  def get_teoric_max_fps(self) -> float:
91
110
  rawdelta = self.clock.get_rawtime()
92
111
  return (1000 / rawdelta) if rawdelta != 0 else 1
93
112
 
94
- def update_screen_mode(self, vsync:None|bool=None, flags=None) -> None:
95
- self.__vsync__ = vsync
96
- self.__flags__ = flags
113
+ def update_screen_mode(self, vsync:Optional[bool]=None, flags:Optional[int]=None, display_index:Optional[int]=None) -> None:
114
+ if vsync is not None: self.__vsync__ = vsync
115
+ if flags is not None: self.__flags__ = flags
116
+ if display_index is not None: self.__display_index__ = display_index
117
+ self.screen = pg.display.set_mode(self.__screen_size__(), vsync=self.__vsync__, flags=self.__flags__, display=self.__display_index__)
97
118
 
98
119
  def sleep(self, seconds:int|float, precise_delay=False) -> None:
99
120
  if precise_delay:
100
- pg.time.delay(seconds * 1000)
121
+ pg.time.delay(int(seconds * 1000))
101
122
  else:
102
- pg.time.wait(seconds * 1000)
123
+ pg.time.wait(int(seconds * 1000))
103
124
 
104
125
  def add_utils(self, *utils:Util) -> None:
105
126
  for util in utils:
106
127
  if util.surface == None: util.surface = self.screen
107
128
  util.rootEnv = self
108
129
  util.id = self.__new_util_id__()
109
- util.render()
130
+ util.__render__()
110
131
  self.utils[util.id] = util
111
132
 
112
133
  def remove_utils(self, *utils:int|str|Util) -> None:
113
134
  for uid in utils:
114
- if uid in self.utils:
115
- del self.utils[uid]
116
- elif isinstance(uid, Util):
135
+ if isinstance(uid, Util):
117
136
  del self.utils[uid.id]
137
+ elif uid in self.utils:
138
+ del self.utils[uid]
118
139
  else:
119
140
  raise Exception(f"Unknown util type: {uid}")
120
141
 
121
142
  def __new_util_id__(self) -> int:
122
143
  if not self.utils: return 0
123
- else: return max(self.utils.keys()) + 1
144
+ else: return len(self.utils.keys()) + 1
124
145
 
125
146
  def get_util(self, uid:int|str) -> Util|None:
126
147
  if isinstance(uid, Util):
@@ -132,7 +153,7 @@ class RootEnv:
132
153
 
133
154
  @property
134
155
  def runtime_seconds(self) -> float:
135
- return pg.time.get_ticks() / 1e3
156
+ return (pg.time.get_ticks() - self.__start_time__) / 1e3
136
157
 
137
158
  def init(self, sub_env:DefEnv) -> None:
138
159
  self.env = sub_env
@@ -155,38 +176,48 @@ class RootEnv:
155
176
  border_radius : int|list[int]|tuple[int,int,int,int] = -1,
156
177
  margin : Vector2D = Vector2D.zero(),
157
178
  personalized_surface : pg.Surface|None = None
158
- ) -> None:
179
+ ) -> Vector2D:
159
180
 
160
181
  text_box = font.render(text, True, color)
161
182
  size = Vector2D(*text_box.get_size()) + margin * 2
162
183
  pivotted_position = position - size * __PIVOT_POSITIONS_MULTIPLIER__[pivot_position] + margin
163
- if not any(isinstance(border_radius, cls) for cls in {tuple, list}): border_radius = [border_radius]*4
184
+ if not any(isinstance(border_radius, cls) for cls in {tuple, list}): border_radius = [border_radius] * 4
164
185
  surface = (self.screen if personalized_surface == None else personalized_surface)
165
186
  if bg_color != None:
166
187
  pg.draw.rect(surface, bg_color, (pivotted_position - margin)() + size(), 0, -1, *border_radius)
167
188
  if border_width:
168
189
  pg.draw.rect(surface, border_color, (pivotted_position - margin)() + size(), border_width, -1, *border_radius)
169
190
  surface.blit(text_box, pivotted_position())
191
+ return size
170
192
 
171
193
  def __draw__(self) -> None:
172
- self.clock.tick(self.target_fps)
194
+ self.__dt__ = self.clock.tick(self.target_fps) / 1000.0
173
195
  self.current_fps = self.clock.get_fps()
196
+ self.fps_label.text = str(round(self.current_fps, 2))
197
+
174
198
  if self.clear_screen_each_frame: self.clear()
175
199
 
176
200
  self.env.draw()
177
- for util in self.utils.values(): util.draw()
201
+ for util in self.utils.values(): util.__draw__()
202
+
203
+ # Save frame first (clean), then draw info overlay (not saved)
204
+ if hasattr(self, "__winrecorder__"):
205
+ self.__winrecorder__.update() # Captures frame without stats
206
+ self.__winrecorder__.draw() # Draws stats on screen only
178
207
 
179
- if self.show_fps: self.print(str(round(self.current_fps,2)), self.screen_size * .01, bg_color=BLACK_COLOR_PYG)
180
208
  pg.display.flip()
181
209
 
182
210
  def __update__(self) -> None:
183
211
  self.mouse.update()
184
212
  self.keyboard.update()
185
213
  self.env.update()
186
- for util in self.utils.values(): util.update()
214
+ for util in self.utils.values(): util.__update__()
187
215
 
188
216
  def frame(self) -> None:
189
- self.events = pg.event.get()
217
+ try:
218
+ self.events = pg.event.get()
219
+ except SystemError:
220
+ raise Warning(f"Pygame error with event drivers. Try restarting the program. If the error persists, try restarting your computer.")
190
221
  self.current_frame += 1
191
222
  self.__update__()
192
223
  self.__draw__()
@@ -194,4 +225,5 @@ class RootEnv:
194
225
  for event in self.events:
195
226
  if event.type == pg.QUIT or ((event.type == pg.KEYDOWN and event.key == self.__quit_on_key_pressed__ and self.selected_util == None) if self.__quit_on_key_pressed__ != None else False):
196
227
  pg.quit()
228
+ if hasattr(self, "__winrecorder__"): self.__winrecorder__.quit()
197
229
  self.quit = True
e2D/utils.py CHANGED
@@ -1,8 +1,8 @@
1
1
  from __future__ import annotations
2
2
  from typing import Any, Callable, Literal
3
3
  import pygame as pg
4
- from e2D import *
5
- from e2D.colors import *
4
+ from e2D import * # type: ignore
5
+ from e2D.colors import * # type: ignore
6
6
 
7
7
  import math as _mt
8
8
 
@@ -18,6 +18,10 @@ def NEW_FONT(size, name:__LITERAL_FONTS__="arial", bold:bool=False, italic:bool=
18
18
  FONT_ARIAL_16 = NEW_FONT(16)
19
19
  FONT_ARIAL_32 = NEW_FONT(32)
20
20
  FONT_ARIAL_64 = NEW_FONT(64)
21
+ FONT_MONOSPACE_16 = NEW_FONT(16, "cascadiamonoregular")
22
+ FONT_MONOSPACE_32 = NEW_FONT(32, "cascadiamonoregular")
23
+ FONT_MONOSPACE_64 = NEW_FONT(64, "cascadiamonoregular")
24
+
21
25
 
22
26
 
23
27
  __LITERAL_PIVOT_POSITIONS__ = Literal["top_left", "top_center", "top_right", "center_left", "center_center", "center_right", "bottom_left", "bottom_center", "bottom_right"]
@@ -33,32 +37,51 @@ __PIVOT_POSITIONS_MULTIPLIER__ = dict(zip(("top_left", "top_center", "top_right"
33
37
  class Mouse:
34
38
  def __init__(self, parent) -> None:
35
39
  self.parent = parent
36
- self.__last_frame_position_count__ = 0
37
- self.__last_frame_position__ = Vector2D.new_zero()
38
- self.__last_frame_movement_count__ = 0
39
- self.__last_frame_movement__ = Vector2D.new_zero()
40
-
40
+ self.__last_frame_position_number__ :int= 0
41
+ self.__last_frame_position__ :Vector2D= Vector2D.new_zero()
42
+ self.__last_frame_movement_number__ :int= 0
43
+ self.__last_frame_movement__ :Vector2D= Vector2D.new_zero()
44
+ self.__last_frame_wheel_number__ :int= 0
45
+ self.__last_frame_wheel_delta__ :int= 0
46
+
41
47
  self.__pressed__ : tuple[bool, bool, bool] = (False, False, False)
42
- self.update()
48
+ self.update()
49
+
50
+ @property
51
+ def wheel_delta(self) -> int:
52
+ for event in self.parent.events:
53
+ if event.type == pg.MOUSEWHEEL:
54
+ if self.__last_frame_wheel_number__ != self.parent.current_frame:
55
+ self.__last_frame_wheel_delta__ = event.y
56
+ self.__last_frame_wheel_number__ = self.parent.current_frame
57
+ return self.__last_frame_wheel_delta__
58
+
59
+ self.__last_frame_wheel_delta__ = 0
60
+ self.__last_frame_wheel_number__ = self.parent.current_frame
61
+ return self.__last_frame_wheel_delta__
43
62
 
44
63
  @property
45
64
  def position(self) -> Vector2D:
46
- if self.__last_frame_position_count__ != self.parent.current_frame:
65
+ if self.__last_frame_position_number__ != self.parent.current_frame:
47
66
  self.__last_frame_position__ = Vector2D(*pg.mouse.get_pos())
48
- self.__last_frame_position_count__ = self.parent.current_frame
67
+ self.__last_frame_position_number__ = self.parent.current_frame
49
68
  return self.__last_frame_position__
50
69
  @position.setter
51
70
  def position(self, new_position:Vector2D) -> None:
52
- self.__last_frame_position_count__ = self.parent.current_frame
71
+ self.__last_frame_position_number__ = self.parent.current_frame
53
72
  self.__last_frame_position__ = new_position
54
73
  pg.mouse.set_pos(self.__last_frame_position__())
55
74
 
56
75
  @property
57
76
  def last_frame_movement(self) -> Vector2D:
58
- if self.__last_frame_movement_count__ != self.parent.current_frame:
77
+ if self.__last_frame_movement_number__ != self.parent.current_frame:
59
78
  self.__last_frame_movement__ = Vector2D(*pg.mouse.get_rel())
60
- self.__last_frame_movement_count__ = self.parent.current_frame
79
+ self.__last_frame_movement_number__ = self.parent.current_frame
61
80
  return self.__last_frame_movement__
81
+ @last_frame_movement.setter
82
+ def last_frame_movement(self, new_movement:Vector2D) -> None:
83
+ self.__last_frame_movement_number__ = self.parent.current_frame
84
+ self.__last_frame_movement__ = new_movement
62
85
 
63
86
  def update(self) -> None:
64
87
  self.__last_pressed__ = self.__pressed__
@@ -95,8 +118,8 @@ class Keyboard:
95
118
 
96
119
  class Util:
97
120
  def __init__(self) -> None:
98
- self.rootEnv = None
99
- self.surface : pg.Surface = pg.SurfaceType
121
+ self.rootEnv : Any
122
+ self.surface : pg.Surface= None # type: ignore
100
123
  self.id : int|str
101
124
  self.is_hovered :bool= False
102
125
  self.hidden :bool= False
@@ -104,9 +127,9 @@ class Util:
104
127
  self.hidden = True
105
128
  def show(self) -> None:
106
129
  self.hidden = False
107
- def render(self) -> None: pass
108
- def draw(self) -> None: pass
109
- def update(self) -> None: pass
130
+ def __render__(self) -> None: pass
131
+ def __draw__(self) -> None: pass
132
+ def __update__(self) -> None: pass
110
133
 
111
134
  class InputCell(Util):
112
135
  def __init__(self,
@@ -176,7 +199,7 @@ class InputCell(Util):
176
199
  def border_color(self, new_color:Color|pg.Color) -> None:
177
200
  self.__border_color__ = pygamize_color(new_color)
178
201
 
179
- def draw(self) -> None:
202
+ def __draw__(self) -> None:
180
203
  if self.hidden: return
181
204
  self.text_surface.fill(TRANSPARENT_COLOR_PYG)
182
205
 
@@ -194,7 +217,7 @@ class InputCell(Util):
194
217
 
195
218
  self.surface.blit(self.text_surface, self.position())
196
219
 
197
- def update(self) -> None:
220
+ def __update__(self) -> None:
198
221
  if self.hidden: return
199
222
  self.is_hovered = self.position.x < self.rootEnv.mouse.position.x < self.position.x + self.size.x and\
200
223
  self.position.y < self.rootEnv.mouse.position.y < self.position.y + self.size.y
@@ -261,7 +284,7 @@ class Slider(Util):
261
284
  self.text_pivot = text_pivot
262
285
 
263
286
  self.handleRadius = handleRadius
264
- self.surface = personalized_surface
287
+ self.surface = personalized_surface # type: ignore
265
288
 
266
289
  self.hidden = False
267
290
 
@@ -281,21 +304,21 @@ class Slider(Util):
281
304
  def handleColour(self, new_color:Color|pg.Color) -> None:
282
305
  self.__handleColour__ = pygamize_color(new_color)
283
306
 
284
- def draw(self) -> None:
307
+ def __draw__(self) -> None:
285
308
  if self.hidden: return
286
- pg.draw.rect(self.rootEnv.screen, self.__color__, self.position() + self.size())
309
+ pg.draw.rect(self.surface, self.__color__, self.position() + self.size())
287
310
 
288
311
  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)
312
+ pg.draw.circle(self.surface, self.__color__, (self.position.x, self.position.y + self.size.y // 2), self.radius)
313
+ pg.draw.circle(self.surface, self.__color__, (self.position.x + self.size.x, self.position.y + self.size.y // 2), self.radius)
291
314
 
292
315
  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
316
 
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)
317
+ pg.draw.circle(self.surface, self.__color__, circle(), self.handleRadius * 1.25)
318
+ pg.draw.circle(self.surface, self.__handleColour__, circle(), self.handleRadius)
296
319
  self.rootEnv.print(self.text.format(round(self.value, 2)), self.position + self.size * self.text_offset, pivot_position=self.text_pivot)
297
320
 
298
- def update(self) -> None:
321
+ def __update__(self) -> None:
299
322
  if self.hidden: return
300
323
  x,y = self.rootEnv.mouse.position
301
324
 
@@ -324,22 +347,22 @@ class Button(Util):
324
347
  text : str,
325
348
  position : V2|Vector2D,
326
349
  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,
350
+ callback : Callable[[], None]|Callable[[], None] = lambda: None,
351
+ default_bg_color : Color|pg.Color = BLUE_COLOR_PYG,
352
+ hovered_bg_color : Color|pg.Color = CYAN_COLOR_PYG,
353
+ border_color : Color|pg.Color = WHITE_COLOR_PYG,
331
354
  text_color : Color|pg.Color = WHITE_COLOR_PYG,
332
355
  font : pg.font.Font = FONT_ARIAL_32,
333
356
  border_radius : float = 10,
334
357
  border_width : float = 10,
335
- starting_hiddden : bool = False,
358
+ starting_hidden : bool = False,
336
359
  args : list = [],
337
360
  activation_mode : __LITERAL_KEY_MODE_TYPES__ = "just_pressed",
338
361
  pivot_position : __LITERAL_PIVOT_POSITIONS__ = "top_left",
339
362
  personalized_surface : pg.Surface|None = None,
340
363
  ) -> None:
341
364
  super().__init__()
342
-
365
+
343
366
  self.text = text
344
367
  self.font = font
345
368
 
@@ -348,10 +371,11 @@ class Button(Util):
348
371
  self.border_radius = border_radius
349
372
  self.__size__ = size
350
373
  self.__border_width__ = border_width
351
-
352
- self.update_position(position, pivot_position)
353
374
 
354
- self.hidden = starting_hiddden
375
+ self.pivot_position :__LITERAL_PIVOT_POSITIONS__= pivot_position
376
+ self.update_position(position)
377
+
378
+ self.hidden = starting_hidden
355
379
  self.args = args
356
380
 
357
381
  self.activation_mode = activation_mode
@@ -359,19 +383,23 @@ class Button(Util):
359
383
  self.hovered = False
360
384
 
361
385
  self.text_color = text_color
362
- self.default_color = default_color
386
+ self.default_bg_color = default_bg_color
363
387
  self.border_color = border_color
364
- self.hovered_color = hovered_color
388
+ self.hovered_bg_color = hovered_bg_color
365
389
 
366
- self.surface = personalized_surface
390
+ self.surface = personalized_surface #type: ignore
367
391
  self.update_surface()
368
392
 
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]
393
+ def update_position(self, new_position:V2) -> None:
394
+ self.position = new_position - self.__size__ * __PIVOT_POSITIONS_MULTIPLIER__[self.pivot_position]
395
+
396
+ def update_pivoting(self, new_pivot_position:__LITERAL_PIVOT_POSITIONS__) -> None:
397
+ self.pivot_position = new_pivot_position
398
+ self.update_position(self.position)
371
399
 
372
400
  def update_surface(self, render=False) -> None:
373
401
  self.buffer_surface = pg.Surface((self.__size__ + self.__border_width__ * 2)(), pg.SRCALPHA, 32).convert_alpha()
374
- if render: self.render()
402
+ if render: self.__render__()
375
403
 
376
404
  @property
377
405
  def size(self) -> V2:
@@ -386,6 +414,7 @@ class Button(Util):
386
414
  return self.__border_width__
387
415
  @border_width.setter
388
416
  def border_width(self, new_width:float) -> None:
417
+ # self.position -= (self.__border_width__ - new_width) * .5
389
418
  self.__border_width__ = new_width
390
419
  self.update_surface(render=True)
391
420
 
@@ -396,11 +425,11 @@ class Button(Util):
396
425
  def text_color(self, new_color:Color|pg.Color) -> None:
397
426
  self.__text_color__ = pygamize_color(new_color)
398
427
  @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)
428
+ def default_bg_color(self) -> Color:
429
+ return unpygamize_color(self.__default_bg_color__)
430
+ @default_bg_color.setter
431
+ def default_bg_color(self, new_color:Color|pg.Color) -> None:
432
+ self.__default_bg_color__ = pygamize_color(new_color)
404
433
  @property
405
434
  def border_color(self) -> Color:
406
435
  return unpygamize_color(self.__border_color__)
@@ -408,27 +437,28 @@ class Button(Util):
408
437
  def border_color(self, new_color:Color|pg.Color) -> None:
409
438
  self.__border_color__ = pygamize_color(new_color)
410
439
  @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")
440
+ def hovered_bg_color(self) -> Color:
441
+ return unpygamize_color(self.__hovered_bg_color__)
442
+ @hovered_bg_color.setter
443
+ def hovered_bg_color(self, new_color:Color|pg.Color) -> None:
444
+ self.__hovered_bg_color__ = pygamize_color(new_color)
445
+
446
+ def __render__(self) -> None:
419
447
  self.buffer_surface.fill(TRANSPARENT_COLOR_PYG)
420
448
 
421
- color = self.__hovered_color__ if self.hovered else self.__default_color__
449
+ color = self.__hovered_bg_color__ if self.hovered else self.__default_bg_color__
422
450
  pg.draw.rect(self.buffer_surface, self.__border_color__, V2.zero()() + (self.size + self.border_width * 2)(), border_radius=self.border_radius)
423
451
  pg.draw.rect(self.buffer_surface, color, (V2.zero() + self.border_width)() + self.size(), border_radius=self.border_radius)
424
452
 
453
+ # TODO:
454
+ # not only size * .5 but also internal pivoting on the corners and sides
425
455
  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
456
 
427
- def draw(self) -> None:
457
+ def __draw__(self) -> None:
428
458
  if self.hidden: return
429
459
  self.surface.blit(self.buffer_surface, (self.position)())
430
460
 
431
- def update(self) -> None:
461
+ def __update__(self) -> None:
432
462
  if self.hidden: return
433
463
 
434
464
  old_overed = self.hovered
@@ -436,15 +466,15 @@ class Button(Util):
436
466
  self.position.x < self.rootEnv.mouse.position.x < self.position.x + self.size.x and \
437
467
  self.position.y < self.rootEnv.mouse.position.y < self.position.y + self.size.y
438
468
  if self.hovered != old_overed:
439
- self.render()
469
+ self.__render__()
440
470
 
441
471
  if self.hovered and self.rootEnv.mouse.get_key(0, self.activation_mode):
442
472
  self.callback(*self.args)
443
473
  self.rootEnv.selected_util = self
444
- self.render()
474
+ self.__render__()
445
475
  elif self.rootEnv.selected_util == self:
446
476
  self.rootEnv.selected_util = None
447
- self.render()
477
+ self.__render__()
448
478
 
449
479
  class Label(Util):
450
480
  def __init__(self,
@@ -457,7 +487,7 @@ class Label(Util):
457
487
  font : pg.font.Font = FONT_ARIAL_32,
458
488
  border_radius : float = 10,
459
489
  border_width : float = 10,
460
- starting_hiddden : bool = False,
490
+ starting_hidden : bool = False,
461
491
  personalized_surface : pg.Surface|None = None,
462
492
  pivot_position : __LITERAL_PIVOT_POSITIONS__ = "top_left",
463
493
  ) -> None:
@@ -470,23 +500,28 @@ class Label(Util):
470
500
  self.__size__ = size
471
501
  self.__border_width__ = border_width
472
502
 
473
- self.position = self.update_position(position, pivot_position)
503
+ self.pivot_position :__LITERAL_PIVOT_POSITIONS__= pivot_position
504
+ self.update_position(position)
474
505
 
475
- self.hidden = starting_hiddden
506
+ self.hidden = starting_hidden
476
507
 
477
508
  self.text_color = text_color
478
509
  self.default_color = default_color
479
510
  self.border_color = border_color
480
511
 
481
- self.surface = personalized_surface
512
+ self.surface = personalized_surface # type: ignore
482
513
  self.update_surface()
483
514
 
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
-
515
+ def update_position(self, new_position:V2) -> None:
516
+ self.position = new_position - (self.__size__ + self.border_width * 2) * __PIVOT_POSITIONS_MULTIPLIER__[self.pivot_position]
517
+
518
+ def update_pivoting(self, new_pivot_position:__LITERAL_PIVOT_POSITIONS__="top_left") -> None:
519
+ self.pivot_position = new_pivot_position
520
+ self.update_position(self.position)
521
+
487
522
  def update_surface(self, render=False) -> None:
488
523
  self.buffer_surface = pg.Surface((self.__size__ + self.__border_width__ * 2)(), pg.SRCALPHA, 32).convert_alpha()
489
- if render: self.render()
524
+ if render: self.__render__()
490
525
 
491
526
  @property
492
527
  def text(self) -> str:
@@ -494,7 +529,7 @@ class Label(Util):
494
529
  @text.setter
495
530
  def text(self, new_text:str) -> None:
496
531
  self.__text__ = new_text
497
- self.render()
532
+ self.__render__()
498
533
 
499
534
  @property
500
535
  def size(self) -> V2:
@@ -531,15 +566,16 @@ class Label(Util):
531
566
  def border_color(self, new_color:Color|pg.Color) -> None:
532
567
  self.__border_color__ = pygamize_color(new_color)
533
568
 
534
- def render(self) -> None:
535
- print("rendering label")
569
+ def __render__(self) -> None:
536
570
  self.buffer_surface.fill(TRANSPARENT_COLOR_PYG)
537
571
 
538
572
  pg.draw.rect(self.buffer_surface, self.__border_color__, V2.zero()() + (self.size + self.border_width * 2)(), border_radius=self.border_radius)
539
573
  pg.draw.rect(self.buffer_surface, self.__default_color__, (V2.zero() + self.border_width)() + self.size(), border_radius=self.border_radius)
540
574
 
575
+ # TODO:
576
+ # not only size * .5 but also internal pivoting on the corners and sides
541
577
  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
578
 
543
- def draw(self) -> None:
579
+ def __draw__(self) -> None:
544
580
  if self.hidden: return
545
581
  self.surface.blit(self.buffer_surface, (self.position)())