comparison cagou/core/widgets_handler.py @ 491:203755bbe0fe

massive refactoring from camelCase -> snake_case. See backend commit log for more details
author Goffi <goffi@goffi.org>
date Sat, 08 Apr 2023 13:44:32 +0200
parents 3c9ba4a694ef
children
comparison
equal deleted inserted replaced
490:962d17c4078c 491:203755bbe0fe
142 if self.screen_manager is None: 142 if self.screen_manager is None:
143 raise exceptions.InternalError( 143 raise exceptions.InternalError(
144 "former_screen_wid can only be used if ScreenManager is used") 144 "former_screen_wid can only be used if ScreenManager is used")
145 if self._former_screen_name is None: 145 if self._former_screen_name is None:
146 return None 146 return None
147 return self.getScreenWidget(self._former_screen_name) 147 return self.get_screen_widget(self._former_screen_name)
148 148
149 def getScreenWidget(self, screen_name): 149 def get_screen_widget(self, screen_name):
150 """Return screen main widget, handling carousel if necessary""" 150 """Return screen main widget, handling carousel if necessary"""
151 if self.carousel is not None and screen_name == '': 151 if self.carousel is not None and screen_name == '':
152 return self.carousel.current_slide 152 return self.carousel.current_slide
153 try: 153 try:
154 return self.screen_manager.get_screen(screen_name).children[0] 154 return self.screen_manager.get_screen(screen_name).children[0]
322 if self._split == 'top': 322 if self._split == 'top':
323 # we remove all top widgets in delete zone, 323 # we remove all top widgets in delete zone,
324 # and update there side widgets list 324 # and update there side widgets list
325 for top in self._top_wids.copy(): 325 for top in self._top_wids.copy():
326 if top.height <= REMOVE_WID_LIMIT: 326 if top.height <= REMOVE_WID_LIMIT:
327 G.host._removeVisibleWidget(top.current_slide) 327 G.host._remove_visible_widget(top.current_slide)
328 for w in top._top_wids: 328 for w in top._top_wids:
329 w._bottom_wids.remove(top) 329 w._bottom_wids.remove(top)
330 w._bottom_wids.update(top._bottom_wids) 330 w._bottom_wids.update(top._bottom_wids)
331 for w in top._bottom_wids: 331 for w in top._bottom_wids:
332 w._top_wids.remove(top) 332 w._top_wids.remove(top)
339 elif self._split == 'left': 339 elif self._split == 'left':
340 # we remove all left widgets in delete zone, 340 # we remove all left widgets in delete zone,
341 # and update there side widgets list 341 # and update there side widgets list
342 for left in self._left_wids.copy(): 342 for left in self._left_wids.copy():
343 if left.width <= REMOVE_WID_LIMIT: 343 if left.width <= REMOVE_WID_LIMIT:
344 G.host._removeVisibleWidget(left.current_slide) 344 G.host._remove_visible_widget(left.current_slide)
345 for w in left._left_wids: 345 for w in left._left_wids:
346 w._right_wids.remove(left) 346 w._right_wids.remove(left)
347 w._right_wids.update(left._right_wids) 347 w._right_wids.update(left._right_wids)
348 for w in left._right_wids: 348 for w in left._right_wids:
349 w._left_wids.remove(left) 349 w._left_wids.remove(left)
358 del self.ellipse 358 del self.ellipse
359 359
360 def clear_widgets(self): 360 def clear_widgets(self):
361 current_slide = self.current_slide 361 current_slide = self.current_slide
362 if current_slide is not None: 362 if current_slide is not None:
363 G.host._removeVisibleWidget(current_slide, ignore_missing=True) 363 G.host._remove_visible_widget(current_slide, ignore_missing=True)
364 364
365 super().clear_widgets() 365 super().clear_widgets()
366 366
367 self.screen_manager = None 367 self.screen_manager = None
368 self.carousel = None 368 self.carousel = None
385 self.screen_manager = ScreenManager() 385 self.screen_manager = ScreenManager()
386 self.main_container.add_widget(self.screen_manager) 386 self.main_container.add_widget(self.screen_manager)
387 parent = Screen() 387 parent = Screen()
388 self.screen_manager.add_widget(parent) 388 self.screen_manager.add_widget(parent)
389 self._former_screen_name = '' 389 self._former_screen_name = ''
390 self.screen_manager.bind(current=self.onScreenChange) 390 self.screen_manager.bind(current=self.on_screen_change)
391 wid.screenManagerInit(self.screen_manager) 391 wid.screen_manager_init(self.screen_manager)
392 else: 392 else:
393 parent = self.main_container 393 parent = self.main_container
394 394
395 if wid.collection_carousel: 395 if wid.collection_carousel:
396 # a Carousel is requested, and this is the first widget that we add 396 # a Carousel is requested, and this is the first widget that we add
399 direction = "right", 399 direction = "right",
400 ignore_perpendicular_swipes = True, 400 ignore_perpendicular_swipes = True,
401 loop = True, 401 loop = True,
402 ) 402 )
403 self._slides_update_lock = 0 403 self._slides_update_lock = 0
404 self.carousel.bind(current_slide=self.onSlideChange) 404 self.carousel.bind(current_slide=self.on_slide_change)
405 parent.add_widget(self.carousel) 405 parent.add_widget(self.carousel)
406 self.carousel.add_widget(wid, index) 406 self.carousel.add_widget(wid, index)
407 else: 407 else:
408 # no Carousel requested, we add the widget as a direct child 408 # no Carousel requested, we add the widget as a direct child
409 parent.add_widget(wid) 409 parent.add_widget(wid)
410 G.host._addVisibleWidget(wid) 410 G.host._add_visible_widget(wid)
411 411
412 def changeWidget(self, new_widget): 412 def change_widget(self, new_widget):
413 """Change currently displayed widget 413 """Change currently displayed widget
414 414
415 slides widgets will be updated 415 slides widgets will be updated
416 """ 416 """
417 if (self.carousel is not None 417 if (self.carousel is not None
418 and self.carousel.current_slide.__class__ == new_widget.__class__): 418 and self.carousel.current_slide.__class__ == new_widget.__class__):
419 # we have the same class, we reuse carousel and screen manager setting 419 # we have the same class, we reuse carousel and screen manager setting
420 420
421 if self.carousel.current_slide != new_widget: 421 if self.carousel.current_slide != new_widget:
422 # slides update need to be blocked to avoid the update in onSlideChange 422 # slides update need to be blocked to avoid the update in on_slide_change
423 # which would mess the removal of current widgets 423 # which would mess the removal of current widgets
424 self._slides_update_lock += 1 424 self._slides_update_lock += 1
425 new_wid = None 425 new_wid = None
426 for w in self.carousel.slides[:]: 426 for w in self.carousel.slides[:]:
427 if w.widget_hash == new_widget.widget_hash: 427 if w.widget_hash == new_widget.widget_hash:
428 new_wid = w 428 new_wid = w
429 continue 429 continue
430 self.carousel.remove_widget(w) 430 self.carousel.remove_widget(w)
431 if isinstance(w, quick_widgets.QuickWidget): 431 if isinstance(w, quick_widgets.QuickWidget):
432 G.host.widgets.deleteWidget(w) 432 G.host.widgets.delete_widget(w)
433 if new_wid is None: 433 if new_wid is None:
434 new_wid = G.host.getOrClone(new_widget) 434 new_wid = G.host.get_or_clone(new_widget)
435 self.carousel.add_widget(new_wid) 435 self.carousel.add_widget(new_wid)
436 self._updateHiddenSlides() 436 self._update_hidden_slides()
437 self._slides_update_lock -= 1 437 self._slides_update_lock -= 1
438 438
439 if self.screen_manager is not None: 439 if self.screen_manager is not None:
440 self.screen_manager.clear_widgets([ 440 self.screen_manager.clear_widgets([
441 s for s in self.screen_manager.screens if s.name != '']) 441 s for s in self.screen_manager.screens if s.name != ''])
442 new_wid.screenManagerInit(self.screen_manager) 442 new_wid.screen_manager_init(self.screen_manager)
443 else: 443 else:
444 # else, we restart fresh 444 # else, we restart fresh
445 self.clear_widgets() 445 self.clear_widgets()
446 self.set_widget(G.host.getOrClone(new_widget)) 446 self.set_widget(G.host.get_or_clone(new_widget))
447 447
448 def onScreenChange(self, screen_manager, new_screen): 448 def on_screen_change(self, screen_manager, new_screen):
449 try: 449 try:
450 new_screen_wid = self.current_slide 450 new_screen_wid = self.current_slide
451 except IndexError: 451 except IndexError:
452 new_screen_wid = None 452 new_screen_wid = None
453 log.warning("Switching to a screen without children") 453 log.warning("Switching to a screen without children")
454 if new_screen == '' and self.carousel is not None: 454 if new_screen == '' and self.carousel is not None:
455 # carousel may have been changed in the background, so we update slides 455 # carousel may have been changed in the background, so we update slides
456 self._updateHiddenSlides() 456 self._update_hidden_slides()
457 former_screen_wid = self.former_screen_wid 457 former_screen_wid = self.former_screen_wid
458 if isinstance(former_screen_wid, cagou_widget.CagouWidget): 458 if isinstance(former_screen_wid, cagou_widget.CagouWidget):
459 G.host._removeVisibleWidget(former_screen_wid) 459 G.host._remove_visible_widget(former_screen_wid)
460 if isinstance(new_screen_wid, cagou_widget.CagouWidget): 460 if isinstance(new_screen_wid, cagou_widget.CagouWidget):
461 G.host._addVisibleWidget(new_screen_wid) 461 G.host._add_visible_widget(new_screen_wid)
462 self._former_screen_name = new_screen 462 self._former_screen_name = new_screen
463 G.host.selected_widget = new_screen_wid 463 G.host.selected_widget = new_screen_wid
464 464
465 def onSlideChange(self, handler, new_slide): 465 def on_slide_change(self, handler, new_slide):
466 if self._former_slide is new_slide: 466 if self._former_slide is new_slide:
467 # FIXME: workaround for Kivy a95d67f (and above?), Carousel.current_slide 467 # FIXME: workaround for Kivy a95d67f (and above?), Carousel.current_slide
468 # binding now calls onSlideChange twice with the same widget (here 468 # binding now calls on_slide_change twice with the same widget (here
469 # "new_slide"). To be checked with Kivy team. 469 # "new_slide"). To be checked with Kivy team.
470 return 470 return
471 log.debug(f"Slide change: new_slide = {new_slide}") 471 log.debug(f"Slide change: new_slide = {new_slide}")
472 if self._former_slide is not None: 472 if self._former_slide is not None:
473 G.host._removeVisibleWidget(self._former_slide, ignore_missing=True) 473 G.host._remove_visible_widget(self._former_slide, ignore_missing=True)
474 self._former_slide = new_slide 474 self._former_slide = new_slide
475 if self.carousel_active: 475 if self.carousel_active:
476 G.host.selected_widget = new_slide 476 G.host.selected_widget = new_slide
477 if new_slide is not None: 477 if new_slide is not None:
478 G.host._addVisibleWidget(new_slide) 478 G.host._add_visible_widget(new_slide)
479 self._updateHiddenSlides() 479 self._update_hidden_slides()
480 480
481 def hiddenList(self, visible_list, ignore=None): 481 def hidden_list(self, visible_list, ignore=None):
482 """return widgets of same class as carousel current one, if they are hidden 482 """return widgets of same class as carousel current one, if they are hidden
483 483
484 @param visible_list(list[QuickWidget]): widgets visible 484 @param visible_list(list[QuickWidget]): widgets visible
485 @param ignore(QuickWidget, None): do no return this widget 485 @param ignore(QuickWidget, None): do no return this widget
486 @return (iter[QuickWidget]): widgets hidden 486 @return (iter[QuickWidget]): widgets hidden
487 """ 487 """
488 # we want to avoid recreated widgets 488 # we want to avoid recreated widgets
489 added = [w.widget_hash for w in visible_list] 489 added = [w.widget_hash for w in visible_list]
490 current_slide = self.carousel.current_slide 490 current_slide = self.carousel.current_slide
491 for w in G.host.widgets.getWidgets(current_slide.__class__, 491 for w in G.host.widgets.get_widgets(current_slide.__class__,
492 profiles=current_slide.profiles): 492 profiles=current_slide.profiles):
493 wid_hash = w.widget_hash 493 wid_hash = w.widget_hash
494 if w in visible_list or wid_hash in added: 494 if w in visible_list or wid_hash in added:
495 continue 495 continue
496 if wid_hash == ignore.widget_hash: 496 if wid_hash == ignore.widget_hash:
497 continue 497 continue
498 yield w 498 yield w
499 499
500 500
501 def _updateHiddenSlides(self): 501 def _update_hidden_slides(self):
502 """adjust carousel slides according to visible widgets""" 502 """adjust carousel slides according to visible widgets"""
503 if self._slides_update_lock or not self.carousel_active: 503 if self._slides_update_lock or not self.carousel_active:
504 return 504 return
505 current_slide = self.carousel.current_slide 505 current_slide = self.carousel.current_slide
506 if not isinstance(current_slide, quick_widgets.QuickWidget): 506 if not isinstance(current_slide, quick_widgets.QuickWidget):
507 return 507 return
508 # lock must be used here to avoid recursions 508 # lock must be used here to avoid recursions
509 self._slides_update_lock += 1 509 self._slides_update_lock += 1
510 visible_list = G.host.getVisibleList(current_slide.__class__) 510 visible_list = G.host.get_visible_list(current_slide.__class__)
511 # we ignore current_slide as it may not be visible yet (e.g. if an other 511 # we ignore current_slide as it may not be visible yet (e.g. if an other
512 # screen is shown 512 # screen is shown
513 hidden = list(self.hiddenList(visible_list, ignore=current_slide)) 513 hidden = list(self.hidden_list(visible_list, ignore=current_slide))
514 slides_sorted = sorted(set(hidden + [current_slide])) 514 slides_sorted = sorted(set(hidden + [current_slide]))
515 to_remove = set(self.carousel.slides).difference({current_slide}) 515 to_remove = set(self.carousel.slides).difference({current_slide})
516 for w in to_remove: 516 for w in to_remove:
517 self.carousel.remove_widget(w) 517 self.carousel.remove_widget(w)
518 if hidden: 518 if hidden:
521 current_idx = slides_sorted.index(current_slide) 521 current_idx = slides_sorted.index(current_slide)
522 try: 522 try:
523 next_slide = slides_sorted[current_idx+1] 523 next_slide = slides_sorted[current_idx+1]
524 except IndexError: 524 except IndexError:
525 next_slide = slides_sorted[0] 525 next_slide = slides_sorted[0]
526 self.carousel.add_widget(G.host.getOrClone(next_slide)) 526 self.carousel.add_widget(G.host.get_or_clone(next_slide))
527 if len(hidden)>1: 527 if len(hidden)>1:
528 previous_slide = slides_sorted[current_idx-1] 528 previous_slide = slides_sorted[current_idx-1]
529 self.carousel.add_widget(G.host.getOrClone(previous_slide)) 529 self.carousel.add_widget(G.host.get_or_clone(previous_slide))
530 530
531 self._slides_update_lock -= 1 531 self._slides_update_lock -= 1
532 532
533 533
534 class WidgetsHandlerLayout(Layout): 534 class WidgetsHandlerLayout(Layout):