mirror of
https://github.com/markqvist/Sideband.git
synced 2024-12-30 09:56:11 -05:00
288 lines
7.2 KiB
Python
288 lines
7.2 KiB
Python
|
"""
|
||
|
Behaviors/Motion
|
||
|
================
|
||
|
|
||
|
.. rubric:: Use motion to make a UI expressive and easy to use.
|
||
|
|
||
|
.. image:: https://github.com/HeaTTheatR/KivyMD-data/raw/master/gallery/kivymddoc/motion.png
|
||
|
:align: center
|
||
|
|
||
|
.. versionadded:: 1.2.0
|
||
|
|
||
|
Classes of the `Motion` type implement the display behavior of widgets such
|
||
|
as dialogs, dropdown menu, snack bars, and so on.
|
||
|
"""
|
||
|
|
||
|
__all__ = (
|
||
|
"MotionBase",
|
||
|
"MotionDropDownMenuBehavior",
|
||
|
"MotionDialogBehavior",
|
||
|
"MotionShackBehavior",
|
||
|
)
|
||
|
|
||
|
from kivy.animation import Animation
|
||
|
from kivy.clock import Clock
|
||
|
from kivy.core.window import Window
|
||
|
from kivy.properties import StringProperty, NumericProperty
|
||
|
|
||
|
from kivymd.uix.behaviors.stencil_behavior import StencilBehavior
|
||
|
|
||
|
|
||
|
class MotionBase:
|
||
|
"""Base class for widget display movement behavior."""
|
||
|
|
||
|
show_transition = StringProperty("linear")
|
||
|
"""
|
||
|
The type of transition of the widget opening.
|
||
|
|
||
|
:attr:`show_transition` is a :class:`~kivy.properties.StringProperty`
|
||
|
and defaults to `'linear'`.
|
||
|
"""
|
||
|
|
||
|
show_duration = NumericProperty(0.2)
|
||
|
"""
|
||
|
Duration of widget display transition.
|
||
|
|
||
|
:attr:`show_duration` is a :class:`~kivy.properties.NumericProperty`
|
||
|
and defaults to `0.2`.
|
||
|
"""
|
||
|
|
||
|
hide_transition = StringProperty("linear")
|
||
|
"""
|
||
|
The type of transition of the widget closing.
|
||
|
|
||
|
:attr:`hide_transition` is a :class:`~kivy.properties.StringProperty`
|
||
|
and defaults to `'linear'`.
|
||
|
"""
|
||
|
|
||
|
hide_duration = NumericProperty(0.2)
|
||
|
"""
|
||
|
Duration of widget closing transition.
|
||
|
|
||
|
:attr:`hide_duration` is a :class:`~kivy.properties.NumericProperty`
|
||
|
and defaults to `0.2`.
|
||
|
"""
|
||
|
|
||
|
|
||
|
class MotionDropDownMenuBehavior(MotionBase):
|
||
|
"""
|
||
|
Base class for the dropdown menu movement behavior.
|
||
|
|
||
|
For more information, see in the :class:`~MotionBase` class documentation.
|
||
|
"""
|
||
|
|
||
|
show_transition = StringProperty("out_back")
|
||
|
"""
|
||
|
The type of transition of the widget opening.
|
||
|
|
||
|
:attr:`show_transition` is a :class:`~kivy.properties.StringProperty`
|
||
|
and defaults to `'out_back'`.
|
||
|
"""
|
||
|
|
||
|
show_duration = NumericProperty(0.4)
|
||
|
"""
|
||
|
Duration of widget display transition.
|
||
|
|
||
|
:attr:`show_duration` is a :class:`~kivy.properties.NumericProperty`
|
||
|
and defaults to `0.2`.
|
||
|
"""
|
||
|
|
||
|
hide_transition = StringProperty("out_cubic")
|
||
|
"""
|
||
|
The type of transition of the widget closing.
|
||
|
|
||
|
:attr:`hide_transition` is a :class:`~kivy.properties.StringProperty`
|
||
|
and defaults to `'out_cubic'`.
|
||
|
"""
|
||
|
|
||
|
_scale_x = NumericProperty(None)
|
||
|
"""
|
||
|
Default X-axis scaling values.
|
||
|
|
||
|
:attr:`_scale_x` is a :class:`~kivy.properties.NumericProperty`
|
||
|
and defaults to `None`.
|
||
|
"""
|
||
|
|
||
|
_scale_y = NumericProperty(None)
|
||
|
"""
|
||
|
Default Y-axis scaling values.
|
||
|
|
||
|
:attr:`_scale_y` is a :class:`~kivy.properties.NumericProperty`
|
||
|
and defaults to `None`.
|
||
|
"""
|
||
|
|
||
|
_opacity = NumericProperty(None)
|
||
|
"""
|
||
|
Menu transparency values.
|
||
|
|
||
|
:attr:`_opacity` is a :class:`~kivy.properties.NumericProperty`
|
||
|
and defaults to `None`.
|
||
|
"""
|
||
|
|
||
|
def __init__(self, **kwargs):
|
||
|
super().__init__(**kwargs)
|
||
|
self.set_scale()
|
||
|
# self.set_opacity()
|
||
|
|
||
|
def set_opacity(self) -> None:
|
||
|
self._opacity = 0
|
||
|
|
||
|
def set_scale(self) -> None:
|
||
|
self._scale_x = 0
|
||
|
self._scale_y = 0
|
||
|
|
||
|
def on_dismiss(self) -> None:
|
||
|
Window.remove_widget(self)
|
||
|
# anim = Animation(
|
||
|
# _scale_x=0,
|
||
|
# _scale_y=0,
|
||
|
# # _opacity=0,
|
||
|
# duration=self.hide_duration,
|
||
|
# transition=self.hide_transition,
|
||
|
# )
|
||
|
# anim.bind(on_complete=lambda *args: Window.remove_widget(self))
|
||
|
# anim.start(self)
|
||
|
|
||
|
def on_open(self, *args):
|
||
|
pass
|
||
|
anim = Animation(
|
||
|
_scale_y=1,
|
||
|
# _opacity=1,
|
||
|
duration=0.0,
|
||
|
transition=self.show_transition,
|
||
|
)
|
||
|
anim &= Animation(
|
||
|
_scale_x=1,
|
||
|
duration=0.0,
|
||
|
transition="out_quad",
|
||
|
)
|
||
|
anim.start(self)
|
||
|
|
||
|
def on__opacity(self, instance, value):
|
||
|
self.opacity = value
|
||
|
|
||
|
def on__scale_x(self, instance, value):
|
||
|
self.scale_value_x = value
|
||
|
|
||
|
def on__scale_y(self, instance, value):
|
||
|
self.scale_value_y = value
|
||
|
|
||
|
|
||
|
class MotionDialogBehavior(MotionBase):
|
||
|
"""
|
||
|
Base class for dialog movement behavior.
|
||
|
|
||
|
For more information, see in the :class:`~MotionBase` class documentation.
|
||
|
"""
|
||
|
|
||
|
show_duration = NumericProperty(0.0)
|
||
|
"""
|
||
|
Duration of widget display transition.
|
||
|
|
||
|
:attr:`show_duration` is a :class:`~kivy.properties.NumericProperty`
|
||
|
and defaults to `0.1`.
|
||
|
"""
|
||
|
|
||
|
scale_x = NumericProperty(1.0)
|
||
|
"""
|
||
|
Default X-axis scaling values.
|
||
|
|
||
|
:attr:`scale_x` is a :class:`~kivy.properties.NumericProperty`
|
||
|
and defaults to `1.5`.
|
||
|
"""
|
||
|
|
||
|
scale_y = NumericProperty(1.0)
|
||
|
"""
|
||
|
Default Y-axis scaling values.
|
||
|
|
||
|
:attr:`scale_y` is a :class:`~kivy.properties.NumericProperty`
|
||
|
and defaults to `1.5`.
|
||
|
"""
|
||
|
|
||
|
def __init__(self, **kwargs):
|
||
|
super().__init__(**kwargs)
|
||
|
self.set_default_values()
|
||
|
|
||
|
def set_default_values(self):
|
||
|
"""Sets default scaled and transparency values."""
|
||
|
|
||
|
self.scale_value_x = self.scale_x
|
||
|
self.scale_value_y = self.scale_y
|
||
|
self.opacity = 0
|
||
|
|
||
|
def on_dismiss(self, *args):
|
||
|
"""Called when a dialog closed."""
|
||
|
|
||
|
self.set_default_values()
|
||
|
|
||
|
def on_open(self, *args):
|
||
|
"""Called when a dialog opened."""
|
||
|
|
||
|
Animation(
|
||
|
opacity=1,
|
||
|
scale_value_x=1,
|
||
|
scale_value_y=1,
|
||
|
t=self.show_transition,
|
||
|
d=self.show_duration,
|
||
|
).start(self)
|
||
|
|
||
|
|
||
|
class MotionShackBehavior(StencilBehavior, MotionBase):
|
||
|
"""
|
||
|
The base class for the behavior of the movement of snack bars.
|
||
|
|
||
|
For more information, see in the
|
||
|
:class:`~MotionBase` class and
|
||
|
:class:`~kivy.uix.behaviors.stencil_behavior.StencilBehavior` class
|
||
|
documentation.
|
||
|
"""
|
||
|
|
||
|
_interval = 0
|
||
|
_height = 0
|
||
|
|
||
|
def on_dismiss(self, *args):
|
||
|
"""Called when a snackbar closed."""
|
||
|
|
||
|
def remove_snackbar(*args):
|
||
|
Window.parent.remove_widget(self)
|
||
|
self.height = self._height
|
||
|
self.dispatch("on_dismiss")
|
||
|
|
||
|
Clock.unschedule(self._wait_interval)
|
||
|
anim = Animation(
|
||
|
opacity=0,
|
||
|
height=0,
|
||
|
t=self.hide_transition,
|
||
|
d=self.hide_duration,
|
||
|
)
|
||
|
anim.bind(on_complete=remove_snackbar)
|
||
|
anim.start(self)
|
||
|
|
||
|
def on_open(self, *args):
|
||
|
"""Called when a snackbar opened."""
|
||
|
|
||
|
def open(*args):
|
||
|
self._height = self.height
|
||
|
self.height = 0
|
||
|
anim = Animation(
|
||
|
opacity=1,
|
||
|
height=self._height,
|
||
|
t=self.show_transition,
|
||
|
d=self.show_duration,
|
||
|
)
|
||
|
anim.bind(
|
||
|
on_complete=lambda *args: Clock.schedule_interval(
|
||
|
self._wait_interval, 1
|
||
|
)
|
||
|
)
|
||
|
anim.start(self)
|
||
|
|
||
|
Clock.schedule_once(open)
|
||
|
self.dispatch("on_open")
|
||
|
|
||
|
def _wait_interval(self, interval):
|
||
|
self._interval += interval
|
||
|
if self._interval > self.duration:
|
||
|
self.dismiss()
|
||
|
self._interval = 0
|