2022-07-07 14:16:10 -06:00
|
|
|
"""
|
|
|
|
Components/ScreenManager
|
|
|
|
========================
|
|
|
|
|
|
|
|
.. versionadded:: 1.0.0
|
|
|
|
|
|
|
|
:class:`~kivy.uix.screenmanager.ScreenManager` class equivalent.
|
2022-10-02 09:16:59 -06:00
|
|
|
If you want to use Hero animations you need to use
|
|
|
|
:class:`~kivymd.uix.screenmanager.MDScreenManager` not
|
|
|
|
:class:`~kivy.uix.screenmanager.ScreenManager` class.
|
2022-10-08 09:17:59 -06:00
|
|
|
|
|
|
|
Transition
|
|
|
|
----------
|
|
|
|
|
|
|
|
:class:`~kivymd.uix.screenmanager.MDScreenManager` class supports the following
|
|
|
|
transitions:
|
|
|
|
|
|
|
|
- :class:`~kivymd.uix.transition.MDFadeSlideTransition`
|
|
|
|
- :class:`~kivymd.uix.transition.MDSlideTransition`
|
|
|
|
- :class:`~kivymd.uix.transition.MDSwapTransition`
|
|
|
|
|
|
|
|
You need to use the :class:`~kivymd.uix.screenmanager.MDScreenManager` class
|
|
|
|
when you want to use hero animations on your screens. If you don't need hero
|
|
|
|
animation use the :class:`~kivy.uix.screenmanager.ScreenManager` class.
|
2022-07-07 14:16:10 -06:00
|
|
|
"""
|
|
|
|
|
2022-10-08 09:17:59 -06:00
|
|
|
from kivy import Logger
|
2022-07-07 14:16:10 -06:00
|
|
|
from kivy.clock import Clock
|
|
|
|
from kivy.properties import ListProperty, StringProperty
|
|
|
|
from kivy.uix.screenmanager import ScreenManager
|
|
|
|
|
2022-10-02 09:16:59 -06:00
|
|
|
from kivymd.uix.behaviors import DeclarativeBehavior
|
2022-07-07 14:16:10 -06:00
|
|
|
from kivymd.uix.hero import MDHeroFrom
|
|
|
|
|
|
|
|
|
2022-10-02 09:16:59 -06:00
|
|
|
class MDScreenManager(DeclarativeBehavior, ScreenManager):
|
2022-07-07 14:16:10 -06:00
|
|
|
"""
|
2022-10-02 09:16:59 -06:00
|
|
|
Screen manager. This is the main class that will control your
|
2022-10-08 09:17:59 -06:00
|
|
|
:class:`~kivymd.uix.screen.MDScreen` stack and memory.
|
|
|
|
|
|
|
|
For more
|
2022-10-02 09:16:59 -06:00
|
|
|
information, see in the :class:`~kivy.uix.screenmanager.ScreenManager`
|
|
|
|
class documentation.
|
|
|
|
"""
|
|
|
|
|
2022-10-08 09:17:59 -06:00
|
|
|
current_hero = StringProperty(None, deprecated=True)
|
2022-10-02 09:16:59 -06:00
|
|
|
"""
|
|
|
|
The name of the current tag for the :class:`~kivymd.uix.hero.MDHeroFrom`
|
|
|
|
and :class:`~kivymd.uix.hero.MDHeroTo` objects that will be animated when
|
2022-07-07 14:16:10 -06:00
|
|
|
animating the transition between screens.
|
|
|
|
|
2022-10-08 09:17:59 -06:00
|
|
|
.. deprecated:: 1.1.0
|
|
|
|
Use :attr:`current_heroes` attribute instead.
|
|
|
|
|
2022-07-07 14:16:10 -06:00
|
|
|
See the `Hero <https://kivymd.readthedocs.io/en/latest/components/hero/>`_
|
2022-10-02 09:16:59 -06:00
|
|
|
module documentation for more information about creating and using Hero
|
|
|
|
animations.
|
2022-07-07 14:16:10 -06:00
|
|
|
|
|
|
|
:attr:`current_hero` is an :class:`~kivy.properties.StringProperty`
|
|
|
|
and defaults to `None`.
|
|
|
|
"""
|
|
|
|
|
2022-10-08 09:17:59 -06:00
|
|
|
current_heroes = ListProperty()
|
|
|
|
"""
|
|
|
|
A list of names (tags) of heroes that need to be animated when moving
|
|
|
|
to the next screen.
|
|
|
|
|
|
|
|
.. versionadded:: 1.1.0
|
|
|
|
|
|
|
|
:attr:`current_heroes` is an :class:`~kivy.properties.ListProperty`
|
|
|
|
and defaults to `[]`.
|
|
|
|
"""
|
|
|
|
|
2022-07-07 14:16:10 -06:00
|
|
|
# Collection of `MDHeroFrom` objects on all screens of the current
|
|
|
|
# screen manager.
|
|
|
|
_heroes_data = ListProperty()
|
|
|
|
|
2022-10-02 09:16:59 -06:00
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
super().__init__(*args, **kwargs)
|
2022-07-07 14:16:10 -06:00
|
|
|
Clock.schedule_once(self.check_transition)
|
|
|
|
|
|
|
|
def check_transition(self, *args) -> None:
|
|
|
|
"""Sets the default type transition."""
|
|
|
|
|
|
|
|
from kivymd.uix.transition.transition import MDTransitionBase
|
|
|
|
|
|
|
|
if not issubclass(self.transition.__class__, MDTransitionBase):
|
|
|
|
from kivymd.uix.transition import MDSlideTransition
|
|
|
|
|
|
|
|
self.transition = MDSlideTransition()
|
|
|
|
|
2022-10-08 09:17:59 -06:00
|
|
|
def get_hero_from_widget(self) -> list:
|
2022-07-07 14:16:10 -06:00
|
|
|
"""
|
2022-10-08 09:17:59 -06:00
|
|
|
Get a list of :class:`~kivymd.uix.hero.MDHeroFrom` objects according
|
|
|
|
to the tag names specified in the :attr:`~current_heroes` list.
|
2022-07-07 14:16:10 -06:00
|
|
|
"""
|
|
|
|
|
2022-10-08 09:17:59 -06:00
|
|
|
hero_from_widget = []
|
2022-07-07 14:16:10 -06:00
|
|
|
|
2022-10-08 09:17:59 -06:00
|
|
|
for name_hero in self.current_heroes:
|
|
|
|
for hero_widget in self._heroes_data:
|
|
|
|
if isinstance(hero_widget, MDHeroFrom) or issubclass(
|
|
|
|
hero_widget.__class__, MDHeroFrom
|
|
|
|
):
|
|
|
|
if hero_widget.tag == name_hero:
|
|
|
|
hero_from_widget.append(hero_widget)
|
2022-07-07 14:16:10 -06:00
|
|
|
|
|
|
|
return hero_from_widget
|
|
|
|
|
2022-10-08 09:17:59 -06:00
|
|
|
def on_current_hero(self, instance, value: str) -> None:
|
|
|
|
"""
|
|
|
|
Called when the value of the :attr:`current_hero` attribute changes.
|
|
|
|
"""
|
|
|
|
|
|
|
|
Logger.warning(
|
|
|
|
"KivyMD: "
|
|
|
|
"`kivymd/uix/screenmanager.MDScreenManager.current_hero` "
|
|
|
|
"attribute is deprecated. "
|
|
|
|
"Use `kivymd/uix/screenmanager.MDScreenManager.current_heroes` "
|
|
|
|
"attribute instead."
|
|
|
|
)
|
|
|
|
if value:
|
|
|
|
self.current_heroes = [value]
|
|
|
|
else:
|
|
|
|
self.current_heroes = []
|
|
|
|
|
2022-07-07 14:16:10 -06:00
|
|
|
def add_widget(self, widget, *args, **kwargs):
|
|
|
|
super().add_widget(widget, *args, **kwargs)
|
|
|
|
Clock.schedule_once(lambda x: self._create_heroes_data(widget))
|
|
|
|
|
2022-10-08 09:17:59 -06:00
|
|
|
# TODO: Add a method to delete an object from the arrt:`_heroes_data`
|
|
|
|
# collection when deleting an object using the `remove_widget` method.
|
|
|
|
|
2022-07-07 14:16:10 -06:00
|
|
|
def _create_heroes_data(self, widget):
|
|
|
|
def find_hero_widget(child_widget):
|
|
|
|
widget_hero = None
|
|
|
|
|
|
|
|
for w in child_widget.children:
|
|
|
|
if isinstance(w, MDHeroFrom) or issubclass(
|
|
|
|
w.__class__, MDHeroFrom
|
|
|
|
):
|
|
|
|
self._heroes_data.append(w)
|
|
|
|
find_hero_widget(w)
|
|
|
|
|
|
|
|
return widget_hero
|
|
|
|
|
|
|
|
for child in widget.children:
|
|
|
|
if isinstance(child, MDHeroFrom) or issubclass(
|
|
|
|
child.__class__, MDHeroFrom
|
|
|
|
):
|
|
|
|
self._heroes_data.append(child)
|
|
|
|
else:
|
|
|
|
find_hero_widget(child)
|