batframework 1.0.8a14__py3-none-any.whl → 1.0.9a2__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.
@@ -58,7 +58,7 @@ class TextInput(Label, InteractiveWidget):
58
58
  def __init__(self) -> None:
59
59
  self.cursor_position = (0, 0)
60
60
  self.old_key_repeat = (0, 0)
61
- self.cursor_timer = bf.Timer(0.3, self._cursor_toggle, loop=True).start()
61
+ self.cursor_timer = bf.Timer(0.2, self._cursor_toggle, loop=True).start()
62
62
  self.cursor_timer.pause()
63
63
  self.show_cursor = False
64
64
  self.on_modify: Callable[[str], str] = None
@@ -110,6 +110,14 @@ class TextInput(Label, InteractiveWidget):
110
110
  return None
111
111
  return lines[line]
112
112
 
113
+ def get_debug_outlines(self):
114
+ if self.visible:
115
+ offset = self._get_outline_offset() if self.show_text_outline else (0,0)
116
+ yield (self.text_rect.move(self.rect.x - offset[0] - self.scroll.x,self.rect.y - offset[1] - self.scroll.y), "purple")
117
+ yield from super().get_debug_outlines()
118
+ yield (self.get_cursor_rect().move(-self.scroll+self.rect.topleft),"green")
119
+
120
+
113
121
  def set_cursor_position(self, position: tuple[int, int]) -> Self:
114
122
  x, y = position
115
123
 
@@ -117,12 +125,30 @@ class TextInput(Label, InteractiveWidget):
117
125
  y = max(0, min(y, len(lines) - 1))
118
126
  line_length = len(lines[y])
119
127
  x = max(0, min(x, line_length))
120
-
121
- self.cursor_position = (x, y)
122
128
  self.show_cursor = True
123
- self.dirty_shape = True
129
+ self.cursor_position = (x,y)
130
+ self.dirty_surface = True
131
+ offset = self._get_outline_offset() if self.show_text_outline else (0,0)
132
+ padded = self.get_padded_rect().move(-self.rect.x + offset[0], -self.rect.y + offset[1])
133
+ self.align_text(self.text_rect,padded,self.alignment)
124
134
  return self
125
135
 
136
+ def get_cursor_rect(self)->pygame.FRect:
137
+ if not self.font_object:
138
+ return pygame.FRect(0,0,0,0)
139
+
140
+ lines = self.text.split('\n')
141
+ line_x, line_y = self.cursor_position
142
+
143
+ height = self.font_object.get_point_size()
144
+
145
+ cursor_y = self.get_padded_rect().__getattribute__(self.alignment.value)[1] - self.rect.top
146
+ cursor_y += line_y * height
147
+ cursor_x = self.text_rect.x
148
+ cursor_x += self.font_object.size(lines[line_y][:line_x])[0] if line_x > 0 else 0
149
+ cursor_rect = pygame.Rect(cursor_x, cursor_y, 1, height)
150
+ return cursor_rect
151
+
126
152
  def cursor_to_absolute(self, position: tuple[int, int]) -> int:
127
153
  x, y = position
128
154
 
@@ -146,68 +172,72 @@ class TextInput(Label, InteractiveWidget):
146
172
  return (len(lines[-1]), len(lines) - 1)
147
173
 
148
174
  def do_handle_event(self, event):
149
- if not self.is_focused:
150
- return
151
-
152
- if event.type not in [pygame.TEXTINPUT, pygame.KEYDOWN]:
175
+ if not self.is_focused or event.type not in [pygame.TEXTINPUT, pygame.KEYDOWN]:
153
176
  return
154
177
 
155
178
  text = self.get_text()
156
- current = self.cursor_to_absolute(self.cursor_position)
179
+ current_pos = self.cursor_to_absolute(self.cursor_position)
180
+ pressed = pygame.key.get_pressed()
181
+
157
182
  if event.type == pygame.TEXTINPUT:
158
- self.set_text(text[:current] + event.text + text[current:])
159
- self.set_cursor_position(self.absolute_to_cursor(current + len(event.text)))
183
+ # Insert text at the current cursor position
184
+ self.set_text(f"{text[:current_pos]}{event.text}{text[current_pos:]}")
185
+ self.set_cursor_position(self.absolute_to_cursor(current_pos + len(event.text)))
186
+
160
187
  elif event.type == pygame.KEYDOWN:
161
- pressed = pygame.key.get_pressed()
162
- if event.key == pygame.K_ESCAPE:
163
- self.lose_focus()
164
- elif event.key == pygame.K_BACKSPACE:
165
- if current > 0:
166
- self.set_text(text[:current - 1] + text[current:])
167
- self.set_cursor_position(self.absolute_to_cursor(current - 1))
168
- elif event.key == pygame.K_DELETE:
169
- if current < len(text):
170
- self.set_text(text[:current] + text[current + 1:])
171
- elif event.key == pygame.K_RIGHT:
172
- if self.cursor_to_absolute(self.cursor_position)>=len(self.text):
188
+ match event.key:
189
+ case pygame.K_ESCAPE:
190
+ self.lose_focus()
191
+
192
+ case pygame.K_BACKSPACE if current_pos > 0:
193
+ # Remove the character before the cursor
194
+ self.set_text(f"{text[:current_pos - 1]}{text[current_pos:]}")
195
+ self.set_cursor_position(self.absolute_to_cursor(current_pos - 1))
196
+
197
+ case pygame.K_DELETE if current_pos < len(text):
198
+ # Remove the character at the cursor
199
+ self.set_text(f"{text[:current_pos]}{text[current_pos + 1:]}")
200
+
201
+ case pygame.K_RIGHT:
202
+ if current_pos < len(text):
203
+ self.handle_cursor_movement(pressed, current_pos, direction="right")
204
+
205
+ case pygame.K_LEFT:
206
+ if current_pos > 0:
207
+ self.handle_cursor_movement(pressed, current_pos, direction="left")
208
+
209
+ case pygame.K_UP:
210
+ # Move cursor up one line
211
+ self.set_cursor_position((self.cursor_position[0], self.cursor_position[1] - 1))
212
+
213
+ case pygame.K_DOWN:
214
+ # Move cursor down one line
215
+ self.set_cursor_position((self.cursor_position[0], self.cursor_position[1] + 1))
216
+
217
+ case pygame.K_RETURN:
218
+ # Insert a newline at the current cursor position
219
+ self.set_text(f"{text[:current_pos]}\n{text[current_pos:]}")
220
+ self.set_cursor_position(self.absolute_to_cursor(current_pos + 1))
221
+ case _ :
173
222
  return
174
- if self.cursor_position[0] == len(self.get_line(self.cursor_position[1])):
175
- self.set_cursor_position((0, self.cursor_position[1] + 1))
176
- else:
177
- if pressed[pygame.K_LCTRL] or pressed[pygame.K_RCTRL]:
178
- index = find_next_word(self.text,current)
179
- if index ==-1 : index = current+1
180
- self.set_cursor_position(self.absolute_to_cursor(index))
181
- else:
182
- self.set_cursor_position(self.absolute_to_cursor(current + 1))
183
- elif event.key == pygame.K_LEFT:
184
-
185
-
186
- if self.cursor_position[0] == 0 and self.cursor_position[1] > 0:
187
- self.set_cursor_position((len(self.get_line(self.cursor_position[1] - 1)), self.cursor_position[1] - 1))
188
- else:
189
- if pressed[pygame.K_LCTRL] or pressed[pygame.K_RCTRL]:
190
- index = find_prev_word(self.text,current-1)
191
- if index ==-1 : index = current-1
192
- self.set_cursor_position(self.absolute_to_cursor(index))
193
- else:
194
- self.set_cursor_position(self.absolute_to_cursor(current - 1))
195
- elif event.key == pygame.K_UP:
196
- x, y = self.cursor_position
197
- self.set_cursor_position((x, y - 1))
198
- elif event.key == pygame.K_DOWN:
199
- x, y = self.cursor_position
200
- self.set_cursor_position((x, y + 1))
201
- elif event.key == pygame.K_RETURN:
202
- self.set_text(text[:current] + '\n' + text[current:])
203
- self.set_cursor_position(self.absolute_to_cursor(current + 1))
204
- else:
205
- return
206
- else:
207
- return
208
223
 
209
224
  event.consumed = True
210
225
 
226
+ def handle_cursor_movement(self, pressed, current_pos, direction):
227
+ if direction == "right":
228
+ if pressed[pygame.K_LCTRL] or pressed[pygame.K_RCTRL]:
229
+ next_word_pos = find_next_word(self.text, current_pos)
230
+ self.set_cursor_position(self.absolute_to_cursor(next_word_pos if next_word_pos != -1 else current_pos + 1))
231
+ else:
232
+ self.set_cursor_position(self.absolute_to_cursor(current_pos + 1))
233
+ elif direction == "left":
234
+ if pressed[pygame.K_LCTRL] or pressed[pygame.K_RCTRL]:
235
+ prev_word_pos = find_prev_word(self.text, current_pos - 1)
236
+ self.set_cursor_position(self.absolute_to_cursor(prev_word_pos if prev_word_pos != -1 else current_pos - 1))
237
+ else:
238
+ self.set_cursor_position(self.absolute_to_cursor(current_pos - 1))
239
+
240
+
211
241
  def set_text(self, text: str) -> Self:
212
242
  if self.on_modify:
213
243
  text = self.on_modify(text)
@@ -216,32 +246,39 @@ class TextInput(Label, InteractiveWidget):
216
246
  def _paint_cursor(self) -> None:
217
247
  if not self.font_object or not self.show_cursor:
218
248
  return
249
+ cursor_rect = self.get_cursor_rect()
250
+ cursor_rect.move_ip(-self.scroll)
219
251
 
220
- lines = self.text.split('\n')
221
- line_x, line_y = self.cursor_position
222
-
223
- cursor_y = self.padding[1]
224
- cursor_y += line_y * self.font_object.get_linesize()
225
- cursor_x = self.padding[0]
226
- cursor_x += self.font_object.size(lines[line_y][:line_x])[0] if line_x > 0 else 0
252
+
253
+ pygame.draw.rect(self.surface, bf.color.CLOUD, cursor_rect.inflate(2,2))
227
254
 
228
- cursor_rect = pygame.Rect(cursor_x, cursor_y, 2, self.font_object.get_height())
229
255
  pygame.draw.rect(self.surface, self.text_color, cursor_rect)
230
256
 
231
257
  def paint(self) -> None:
232
258
  super().paint()
233
259
  self._paint_cursor()
234
260
 
235
- # def set_alignment(self, alignment: bf.alignment) -> Self:
236
- # return self
237
-
238
- # def align_text(
239
- # self, text_rect: pygame.FRect, area: pygame.FRect, alignment: bf.alignment
240
- # ):
241
- # if alignment == bf.alignment.LEFT:
242
- # alignment = bf.alignment.MIDLEFT
243
- # elif alignment == bf.alignment.MIDRIGHT:
244
- # alignment = bf.alignment.MIDRIGHT
245
- # pos = area.__getattribute__(alignment.value)
246
- # text_rect.__setattr__(alignment.value, pos)
247
- # return
261
+ def align_text(
262
+ self, text_rect: pygame.FRect, area: pygame.FRect, alignment: bf.alignment
263
+ ):
264
+ cursor_rect = self.get_cursor_rect()
265
+
266
+ if alignment == bf.alignment.LEFT:
267
+ alignment = bf.alignment.MIDLEFT
268
+ elif alignment == bf.alignment.MIDRIGHT:
269
+ alignment = bf.alignment.MIDRIGHT
270
+ pos = area.__getattribute__(alignment.value)
271
+ text_rect.__setattr__(alignment.value, pos)
272
+
273
+
274
+ if cursor_rect.right > area.right+self.scroll.x:
275
+ self.scroll.x=cursor_rect.right - area.right
276
+ elif cursor_rect.x < self.scroll.x+area.left:
277
+ self.scroll.x= cursor_rect.left - area.left
278
+ self.scroll.x = max(self.scroll.x,0)
279
+
280
+ if cursor_rect.bottom > area.bottom + self.scroll.y:
281
+ self.scroll.y = cursor_rect.bottom - area.bottom
282
+ elif cursor_rect.y < self.scroll.y + area.top:
283
+ self.scroll.y = cursor_rect.top - area.top
284
+ self.scroll.y = max(self.scroll.y, 0)
@@ -14,7 +14,6 @@ class Toggle(Button):
14
14
  super().__init__(text, callback)
15
15
  self.add(self.indicator)
16
16
  self.set_clip_children(False)
17
- # self.set_gap(int(max(4, self.get_padded_width() / 3)))
18
17
 
19
18
  def set_visible(self, value: bool) -> Self:
20
19
  self.indicator.set_visible(value)
@@ -77,17 +76,16 @@ class Toggle(Button):
77
76
  0, 0, self.text_rect.w + gap + self.indicator.rect.w, self.text_rect.h
78
77
  )
79
78
 
80
-
81
79
  if self.autoresize_h or self.autoresize_w:
82
80
  target_rect = self.inflate_rect_by_padding(joined_rect)
81
+ target_rect.h += self.unpressed_relief
83
82
  if not self.autoresize_w:
84
83
  target_rect.w = self.rect.w
85
84
  if not self.autoresize_h:
86
85
  target_rect.h = self.rect.h
87
86
  if self.rect.size != target_rect.size:
88
87
  self.set_size(target_rect.size)
89
- self.build()
90
- return
88
+ self.apply_updates()
91
89
 
92
90
  # ------------------------------------ size is ok
93
91
 
@@ -11,9 +11,7 @@ MAX_CONSTRAINTS = 10
11
11
 
12
12
  class WidgetMeta(type):
13
13
  def __call__(cls, *args, **kwargs):
14
- """Called when you call MyNewClass()"""
15
14
  obj = type.__call__(cls, *args, **kwargs)
16
- # obj.new_init()
17
15
  bf.StyleManager().register_widget(obj)
18
16
  return obj
19
17
 
@@ -28,10 +26,9 @@ class Widget(bf.Drawable, metaclass=WidgetMeta):
28
26
  self.clip_children: bool = True
29
27
  self.padding = (0, 0, 0, 0)
30
28
  self.dirty_surface: bool = True # if true will call paint before drawing
31
- self.dirty_shape: bool = (
32
- True # if true will call (build+paint) before drawing
33
- )
34
- self.dirty_constraints: bool = False
29
+ self.dirty_shape: bool = True # if true will call (build+paint) before drawing
30
+ self.dirty_constraints: bool = False # if true will call resolve_constraints
31
+
35
32
  self.is_root: bool = False
36
33
  self.autoresize_w, self.autoresize_h = True, True
37
34
  self.__constraint_iteration = 0
@@ -221,7 +218,7 @@ class Widget(bf.Drawable, metaclass=WidgetMeta):
221
218
  if capture != self.__constraints_capture:
222
219
  self.__constraints_capture = capture
223
220
  self.__constraint_to_ignore = []
224
-
221
+
225
222
  constraints = self.constraints.copy()
226
223
  # If all are resolved early exit
227
224
  if all(c.evaluate(self.parent,self) for c in constraints if c not in self.__constraint_to_ignore):
@@ -240,6 +237,7 @@ class Widget(bf.Drawable, metaclass=WidgetMeta):
240
237
  for c in constraints:
241
238
  if c in self.__constraints_to_ignore:continue
242
239
  if not c.evaluate(self.parent,self) :
240
+ # print(c," is applied")
243
241
  c.apply(self.parent,self)
244
242
  # second pass where we check conflicts
245
243
  for c in constraints:
@@ -256,9 +254,10 @@ class Widget(bf.Drawable, metaclass=WidgetMeta):
256
254
 
257
255
  if self.__constraints_to_ignore:
258
256
  print("Constraints ignored : ",[str(c) for c in self.__constraints_to_ignore])
259
-
260
-
257
+
261
258
  self.dirty_constraints = False
259
+ # print(self,self.uid,"resolve constraints : Success")
260
+
262
261
 
263
262
  def has_constraint(self, name: str) -> bool:
264
263
  return any(c.name == name for c in self.constraints)
@@ -313,17 +312,16 @@ class Widget(bf.Drawable, metaclass=WidgetMeta):
313
312
  size[0] = self.rect.w
314
313
  if size[1] is None:
315
314
  size[1] = self.rect.h
316
- if size == self.rect.size:
315
+ if (int(size[0]),int(size[1])) == (int(self.rect.w),int(self.rect.h)):
317
316
  return self
318
317
  self.rect.size = size
319
318
  self.dirty_shape = True
320
319
  return self
321
320
 
322
- def process_event(self, event: pygame.Event) -> bool:
321
+ def process_event(self, event: pygame.Event) -> None:
323
322
  # First propagate to children
324
323
  for child in self.children:
325
324
  child.process_event(event)
326
- # return True if the method is blocking (no propagation to next children of the scene)
327
325
  super().process_event(event)
328
326
 
329
327
  def update(self, dt) -> None:
@@ -351,7 +349,7 @@ class Widget(bf.Drawable, metaclass=WidgetMeta):
351
349
  if top_down:
352
350
  func(self, *args, **kwargs)
353
351
  for child in self.children:
354
- child.visit(func, top_down)
352
+ child.visit(func, top_down,*args,**kwargs)
355
353
  if not top_down:
356
354
  func(self, *args, **kwargs)
357
355
 
@@ -361,55 +359,69 @@ class Widget(bf.Drawable, metaclass=WidgetMeta):
361
359
  if self.parent:
362
360
  self.parent.visit_up(func, *args, **kwargs)
363
361
 
364
- def selective_up(self, widget: "Widget"):
365
- # if returns True then stop climbing widget tree
366
- if widget.parent and widget.parent.dirty_constraints:
367
- return False
368
- widget.visit(self.selective_down)
369
- return True
362
+ """
363
+ 1 :
364
+ bottom up -> only build children
370
365
 
371
- def selective_down(self, widget: "Widget"):
372
- if widget.constraints:
373
- widget.resolve_constraints()
374
- else:
375
- widget.dirty_constraints = False
366
+ """
367
+ def update_children_size(self, widget: "Widget"):
368
+ # print(widget,widget.uid,"constraints resolve in update size func")
369
+
370
+ widget.resolve_constraints()
376
371
  if widget.dirty_shape:
372
+ # print(widget,widget.uid,"build in update size func")
377
373
  widget.build()
378
374
  widget.dirty_shape = False
379
- self.dirty_surface = True
375
+ widget.dirty_surface = True
376
+
377
+ def find_highest_dirty_constraints_widget(self) -> "Widget":
378
+ w = self
379
+ tmp = w
380
+ while not tmp.is_root:
381
+ if tmp.dirty_constraints or tmp.dirty_shape:
382
+ w = tmp
383
+ if not tmp.parent:
384
+ break
385
+ tmp = tmp.parent
386
+ return w
380
387
 
381
- def draw(self, camera: bf.Camera) -> None:
388
+
389
+ def apply_updates(self) -> None:
390
+ # Step 1: Build shape if needed
382
391
  if self.dirty_shape:
383
- self.dirty_constraints = True
384
- self.dirty_surface = True
385
- self.build()
392
+ self.build() # Finalize widget size
386
393
  self.dirty_shape = False
394
+ self.dirty_surface = True
395
+ # Propagate dirty_constraints to children in case size affects their position
387
396
  for child in self.children:
388
397
  child.dirty_constraints = True
389
398
 
399
+ # Step 2: Resolve constraints now that size is finalized
390
400
  if self.dirty_constraints:
391
- if self.parent and self.parent.dirty_constraints:
392
- self.parent.visit_up(self.selective_up)
393
- else:
394
- self.visit(lambda c: c.resolve_constraints())
401
+ self.resolve_constraints() # Finalize positioning based on final size
402
+ self.dirty_constraints = False
395
403
 
404
+ # Step 3: Paint the surface if flagged as dirty
396
405
  if self.dirty_surface:
397
406
  self.paint()
398
407
  self.dirty_surface = False
408
+
399
409
 
410
+
411
+ def draw(self, camera: bf.Camera) -> None:
412
+ self.apply_updates()
413
+ # Draw widget and handle clipping if necessary
400
414
  super().draw(camera)
401
415
 
402
416
  if self.clip_children:
403
-
404
417
  new_clip = camera.world_to_screen(self.get_padded_rect())
405
418
  old_clip = camera.surface.get_clip()
406
419
  new_clip = new_clip.clip(old_clip)
407
420
  camera.surface.set_clip(new_clip)
408
421
 
409
- _ = [
422
+ # Draw each child widget, sorted by render order
423
+ for child in sorted(self.children, key=lambda c: c.render_order):
410
424
  child.draw(camera)
411
- for child in sorted(self.children, key=lambda c: c.render_order)
412
- ]
413
425
 
414
426
  if self.clip_children:
415
427
  camera.surface.set_clip(old_clip)
batFramework/manager.py CHANGED
@@ -14,11 +14,12 @@ class Manager(bf.SceneManager):
14
14
  self.is_async_running : bool = False
15
15
  self.running = False
16
16
  pygame.mouse.set_cursor(bf.const.DEFAULT_CURSOR)
17
- self.do_pre_init()
18
- self.init_scenes(*initial_scene_list)
19
17
  bf.ResourceManager().set_sharedVar("clock", self.clock)
20
18
  bf.ResourceManager().set_sharedVar("debug_mode", self.debug_mode)
21
-
19
+
20
+ self.do_pre_init()
21
+ if initial_scene_list:
22
+ self.init_scenes(*initial_scene_list)
22
23
  self.do_init()
23
24
 
24
25
  @staticmethod
@@ -58,65 +59,75 @@ class Manager(bf.SceneManager):
58
59
  def stop(self) -> None:
59
60
  self.running = False
60
61
 
62
+ def process_event(self, event: pygame.Event):
63
+ event.consumed = False
64
+ keys = pygame.key.get_pressed()
65
+ if (
66
+ bf.const.ALLOW_DEBUG and
67
+ keys[pygame.K_LCTRL]
68
+ and keys[pygame.K_LSHIFT]
69
+ and event.type == pygame.KEYDOWN
70
+ ):
71
+ if event.key == pygame.K_d:
72
+ self.cycle_debug_mode()
73
+ return
74
+ if event.key == pygame.K_p:
75
+ self.print_status()
76
+ return
77
+ super().process_event(event)
78
+ if not event.consumed:
79
+ if event.type == pygame.QUIT:
80
+ self.running = False
81
+ elif event.type == pygame.VIDEORESIZE and not (
82
+ bf.const.FLAGS & pygame.SCALED
83
+ ):
84
+ bf.const.set_resolution((event.w, event.h))
85
+
86
+ def update(self, dt: float) -> None:
87
+ self.timeManager.update(dt)
88
+ self.cutsceneManager.update(dt)
89
+ super().update(dt)
90
+
91
+
61
92
  async def run_async(self):
93
+ if len(self.scenes) == 0:
94
+ raise Exception("Manager can't start without scenes")
62
95
  if self.running:
63
- print("Error : Already running")
96
+ raise Exception("Error : Already running")
64
97
  return
65
98
  self.is_async_running = True
66
99
  self.running = True
67
100
  dt: float = 0
68
101
  while self.running:
69
102
  for event in pygame.event.get():
70
- event.consumed = False
71
103
  self.process_event(event)
72
- if not event.consumed:
73
- if event.type == pygame.QUIT:
74
- self.running = False
75
- break
76
- if event.type == pygame.VIDEORESIZE and not (
77
- bf.const.FLAGS & pygame.SCALED
78
- ):
79
- bf.const.set_resolution((event.w, event.h))
80
104
  # update
81
- self.timeManager.update(dt)
82
- self.cutsceneManager.update(dt)
83
105
  self.update(dt)
84
106
  # render
85
- self.screen.fill((0, 0, 0))
86
107
  self.draw(self.screen)
87
108
  pygame.display.flip()
88
109
  dt = self.clock.tick(bf.const.FPS) / 1000
89
- # dt = min(dt, 0.02) dirty fix for dt being too high when window not focused for a long time
110
+ dt = min(dt, 0.02) # dirty fix for dt being too high when window not focused for a long time
90
111
  await asyncio.sleep(0)
91
112
  pygame.quit()
92
113
 
93
114
 
94
115
  def run(self) -> None:
116
+ if len(self.scenes) == 0:
117
+ raise Exception("Manager can't start without scenes")
95
118
  if self.running:
96
- print("Error : Already running")
119
+ raise Exception("Error : Already running")
97
120
  return
98
121
  self.running = True
99
122
  dt: float = 0
100
123
  while self.running:
101
124
  for event in pygame.event.get():
102
- event.consumed = False
103
125
  self.process_event(event)
104
- if not event.consumed:
105
- if event.type == pygame.QUIT:
106
- self.running = False
107
- break
108
- if event.type == pygame.VIDEORESIZE and not (
109
- bf.const.FLAGS & pygame.SCALED
110
- ):
111
- bf.const.set_resolution((event.w, event.h))
112
126
  # update
113
- self.timeManager.update(dt)
114
- self.cutsceneManager.update(dt)
115
127
  self.update(dt)
116
128
  # render
117
- self.screen.fill((0, 0, 0))
118
129
  self.draw(self.screen)
119
130
  pygame.display.flip()
120
131
  dt = self.clock.tick(bf.const.FPS) / 1000
121
- # dt = min(dt, 0.02) dirty fix for dt being too high when window not focused for a long time
132
+ dt = min(dt, 0.02) # dirty fix for dt being too high when window not focused for a long time
122
133
  pygame.quit()
@@ -166,21 +166,11 @@ class SceneManager:
166
166
  def cycle_debug_mode(self):
167
167
  current_index = bf.ResourceManager().get_sharedVar("debug_mode").value
168
168
  next_index = (current_index + 1) % len(bf.debugMode)
169
+ bf.ResourceManager().set_sharedVar("debug_mode", bf.debugMode(next_index))
169
170
  return bf.debugMode(next_index)
170
171
 
171
172
  def process_event(self, event: pygame.Event):
172
- keys = pygame.key.get_pressed()
173
- if (
174
- keys[pygame.K_LCTRL]
175
- and keys[pygame.K_LSHIFT]
176
- and event.type == pygame.KEYDOWN
177
- ):
178
- if event.key == pygame.K_d:
179
- bf.ResourceManager().set_sharedVar("debug_mode", self.cycle_debug_mode())
180
- return
181
- if event.key == pygame.K_p:
182
- self.print_status()
183
- return
173
+
184
174
  if event.type in self.shared_events:
185
175
  [s.process_event(event) for s in self.scenes]
186
176
  else:
@@ -16,7 +16,7 @@ class ScrollingSprite(bf.Sprite):
16
16
 
17
17
  # Use integer values for the starting points, converted from floating point scroll values
18
18
 
19
- super().__init__(data, size, convert_alpha)
19
+ super().__init__(size, data, convert_alpha)
20
20
  self.original_width, self.original_height = self.original_surface.get_size()
21
21
 
22
22
  def get_debug_outlines(self):
batFramework/utils.py CHANGED
@@ -81,7 +81,6 @@ class Utils:
81
81
 
82
82
 
83
83
  @staticmethod
84
- @cache
85
84
  def create_spotlight(inside_color, outside_color, radius, radius_stop=None, dest_surf=None,size=None):
86
85
  """
87
86
  Creates a spotlight effect on a surface with a gradient from inside_color to outside_color.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: batframework
3
- Version: 1.0.8a14
3
+ Version: 1.0.9a2
4
4
  Summary: Pygame framework for making games easier.
5
5
  Author-email: Turan Baturay <baturayturan@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/TuranBaturay/batFramework