166 lines
5.4 KiB
Python
166 lines
5.4 KiB
Python
import time
|
|
import random
|
|
|
|
from kivy.clock import Clock
|
|
from kivy.uix.screenmanager import ScreenManager, FadeTransition
|
|
from kivy.uix.screenmanager import Screen as BaseScreen
|
|
from kivy.uix.relativelayout import RelativeLayout
|
|
import kivy.uix.screenmanager
|
|
|
|
from kivy.properties import StringProperty, NumericProperty, BooleanProperty, ObjectProperty, OptionProperty
|
|
|
|
class NodeBehavior(object):
|
|
'''Screen is an element intended to be used with a :class:`ScreenManager`.
|
|
Check module documentation for more information.
|
|
:Events:
|
|
`on_pre_enter`: ()
|
|
Event fired when the screen is about to be used: the entering
|
|
animation is started.
|
|
`on_enter`: ()
|
|
Event fired when the screen is displayed: the entering animation is
|
|
complete.
|
|
`on_pre_leave`: ()
|
|
Event fired when the screen is about to be removed: the leaving
|
|
animation is started.
|
|
`on_leave`: ()
|
|
Event fired when the screen is removed: the leaving animation is
|
|
finished.
|
|
.. versionchanged:: 1.6.0
|
|
Events `on_pre_enter`, `on_enter`, `on_pre_leave` and `on_leave` were
|
|
added.
|
|
'''
|
|
|
|
name = StringProperty('')
|
|
'''
|
|
Name of the screen which must be unique within a :class:`ScreenManager`.
|
|
This is the name used for :attr:`ScreenManager.current`.
|
|
:attr:`name` is a :class:`~kivy.properties.StringProperty` and defaults to
|
|
''.
|
|
'''
|
|
|
|
manager = ObjectProperty(None, allownone=True)
|
|
''':class:`ScreenManager` object, set when the screen is added to a
|
|
manager.
|
|
:attr:`manager` is an :class:`~kivy.properties.ObjectProperty` and
|
|
defaults to None, read-only.
|
|
'''
|
|
|
|
transition_progress = NumericProperty(0.)
|
|
'''Value that represents the completion of the current transition, if any
|
|
is occurring.
|
|
If a transition is in progress, whatever the mode, the value will change
|
|
from 0 to 1. If you want to know if it's an entering or leaving animation,
|
|
check the :attr:`transition_state`.
|
|
:attr:`transition_progress` is a :class:`~kivy.properties.NumericProperty`
|
|
and defaults to 0.
|
|
'''
|
|
|
|
transition_state = OptionProperty('out', options=('in', 'out'))
|
|
'''Value that represents the state of the transition:
|
|
- 'in' if the transition is going to show your screen
|
|
- 'out' if the transition is going to hide your screen
|
|
After the transition is complete, the state will retain it's last value (in
|
|
or out).
|
|
:attr:`transition_state` is an :class:`~kivy.properties.OptionProperty` and
|
|
defaults to 'out'.
|
|
'''
|
|
|
|
__events__ = ('on_pre_enter', 'on_enter', 'on_pre_leave', 'on_leave')
|
|
|
|
interval = NumericProperty(0.0)
|
|
|
|
def on_pre_enter(self, *args):
|
|
pass
|
|
|
|
def on_enter(self, *args):
|
|
pass
|
|
|
|
def on_pre_leave(self, *args):
|
|
pass
|
|
|
|
def on_leave(self, *args):
|
|
pass
|
|
|
|
def __repr__(self):
|
|
return '<Screen name=%r>' % self.name
|
|
|
|
class Node(NodeBehavior, RelativeLayout):
|
|
pass
|
|
|
|
kivy.uix.screenmanager.Screen = NodeBehavior
|
|
Screen = Node
|
|
|
|
class Fader(ScreenManager):
|
|
interval = NumericProperty(5.0)
|
|
view_start = NumericProperty(5.0)
|
|
show_progress = BooleanProperty(True)
|
|
|
|
_interval = None
|
|
_progress_interval = None
|
|
|
|
def __init__(self, **kwargs):
|
|
super(Fader, self).__init__(**kwargs)
|
|
if 'transition' not in kwargs:
|
|
self.transition = FadeTransition()
|
|
|
|
from kivy.graphics import Color, Rectangle
|
|
with self.canvas.after:
|
|
Color(1., 1., 1., 0.2)
|
|
self.progress_rect = Rectangle(pos=self.pos, size=(0, 0))
|
|
|
|
self.on_show_progress(None, self.show_progress)
|
|
self.rotate_screens(0)
|
|
|
|
def update_rect(self, *args):
|
|
if not self.show_progress:
|
|
return
|
|
progress = ((time.time() - self.view_start)/self.current_interval)
|
|
|
|
self.progress_rect.pos = self.pos
|
|
self.progress_rect.size = (self.size[0] * progress, 10)
|
|
|
|
def on_show_progress(self, instance, value):
|
|
if self._progress_interval:
|
|
self._progress_interval.cancel()
|
|
self._progress_interval = None
|
|
|
|
if value:
|
|
self._progress_interval = Clock.schedule_interval(self.update_rect, 0)
|
|
|
|
self.progress_rect.size = (0, 0)
|
|
|
|
def on_interval(self, instance, value):
|
|
if self._interval:
|
|
self._interval.cancel()
|
|
self._interval = Clock.schedule_once(
|
|
self.rotate_screens, self.current_interval)
|
|
|
|
def add_widget(self, screen):
|
|
"""Just wrap everything in Screen"""
|
|
if not isinstance(screen, NodeBehavior):
|
|
print ('Wrapping!', screen)
|
|
s = Node()
|
|
s.add_widget(screen)
|
|
screen = s
|
|
return super(Fader, self).add_widget(screen)
|
|
|
|
def generate_ids(self):
|
|
"""Generates random IDs for all screens without set name"""
|
|
for i, c in enumerate(self.screens):
|
|
if not c.name:
|
|
c.name = 'screen_%i_%s' % (i, type(c))
|
|
|
|
def rotate_screens(self, dt):
|
|
self.generate_ids()
|
|
self.current = self.next()
|
|
self.view_start = time.time()
|
|
|
|
self._interval = Clock.schedule_once(
|
|
self.rotate_screens, self.current_interval)
|
|
|
|
@property
|
|
def current_interval(self):
|
|
if self.current_screen and self.current_screen.interval:
|
|
return self.current_screen.interval
|
|
return self.interval
|