Created
June 15, 2015 08:43
-
-
Save rnixx/2aab5e13e17c1582b6dd to your computer and use it in GitHub Desktop.
Kivy: Extended Screen manager with better convenience for switching between screens.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from kivy.uix.screenmanager import ScreenManager | |
from kivy.uix.screenmanager import ScreenManagerException | |
from kivy.uix.screenmanager import Screen | |
class ExtScreenManager(ScreenManager): | |
def __init__(self, **kwargs): | |
Logger.debug('ExtScreenManager.__init__') | |
self.register_event_type('on_finish_screen_switch') | |
super(ExtScreenManager, self).__init__(**kwargs) | |
def on_finish_screen_switch(self, *args): | |
"""Default handler. | |
""" | |
Logger.debug('ExtScreenManager.on_finish_screen_switch') | |
def display_screen(self, screen, **options): | |
"""Display screen. | |
Given ``screen`` can be either a screen instance or a screen name as | |
string. | |
If screen instance is given and not child of manager yet, it gets added | |
as long as no screen with same name already exists. | |
If screen name is given, corresponding screen must already be contained | |
in manager. | |
``options`` might contain a :attr:`remove` flag, which causes the | |
already displayed screen to be removed after switching to given screen. | |
:attr:`transition` instance can be given in ``options`` to use a | |
custom transition for this screen switch. | |
""" | |
Logger.debug('ExtScreenManager.display_screen') | |
# screen must be given | |
assert(screen is not None) | |
# flag whether to add given screen | |
add_screen = False | |
# remember currently displayed screen | |
current_screen = self.current_screen | |
# screen instance given | |
if isinstance(screen, Screen): | |
# given screen already displayed | |
if current_screen is screen: | |
return | |
screen_name = screen.name | |
# screen not contained in self | |
if screen not in self.screens: | |
# screen with name already contained | |
if self.has_screen(screen_name): | |
raise ScreenManagerException( | |
'Screen with name {0} already exists'.format( | |
screen_name | |
) | |
) | |
# screen needs to be added | |
add_screen = True | |
# no screen instance | |
else: | |
# screen name expected | |
if not isinstance(screen, string_types): | |
raise ScreenManagerException( | |
'Given screen must be either Screen instance or screen ' | |
'name as string' | |
) | |
screen_name = screen | |
# no screen with given name in self | |
if not self.has_screen(screen_name): | |
raise ScreenManagerException( | |
'No screen found for given screen name' | |
) | |
# given screen already displayed | |
if current_screen and current_screen.name == screen_name: | |
return | |
# option whether to remove previous screen | |
remove_prev = options.pop("remove", False) | |
# custom transition to use | |
custom_transition = options.pop("transition", None) | |
# remember original transition | |
orgin_transition = self.transition | |
# use custom transition if given | |
if custom_transition: | |
# update transition options | |
for key, value in iteritems(options): | |
setattr(custom_transition, key, value) | |
# set transition | |
self.transition = custom_transition | |
def finish_screen_switch(transition): | |
# remove previous screen | |
if remove_prev and current_screen in self.children: | |
self.remove_widget(current_screen) | |
# reset transition | |
if custom_transition: | |
self.transition = orgin_transition | |
# unbind callback | |
transition.unbind(on_complete=finish_screen_switch) | |
self.dispatch('on_finish_screen_switch') | |
# bind callback | |
self.transition.bind(on_complete=finish_screen_switch) | |
# add screen if necessary | |
if add_screen: | |
# initial display | |
initial = self.current is None | |
# add screen | |
self.add_widget(screen) | |
# current gets set on add_widget if initial display | |
if not initial: | |
self.current = screen_name | |
# set current screen | |
else: | |
self.current = screen_name |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment