test-kivy-app/kivy_venv/lib/python3.11/site-packages/kivy/effects/scroll.py
2024-09-15 15:12:16 +03:00

127 lines
4.0 KiB
Python

'''
Scroll effect
=============
.. versionadded:: 1.7.0
Based on the :class:`~kivy.effects.kinetic` effect, the :class:`ScrollEffect`
will limit the movement to bounds determined by its :attr:`~ScrollEffect.min`
and :attr:`~ScrollEffect.max` properties. If the movement exceeds these
bounds, it will calculate the amount of :attr:`~ScrollEffect.overscroll` and
try to return to the value of one of the bounds.
This is very useful for implementing a scrolling list. We actually use this
class as a base effect for our :class:`~kivy.uix.scrollview.ScrollView` widget.
'''
__all__ = ('ScrollEffect', )
from time import time
from kivy.effects.kinetic import KineticEffect
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ObjectProperty
class ScrollEffect(KineticEffect):
'''ScrollEffect class. See the module documentation for more information.
'''
drag_threshold = NumericProperty('20sp')
'''Minimum distance to travel before the movement is considered as a drag.
:attr:`drag_threshold` is a :class:`~kivy.properties.NumericProperty` and
defaults to 20sp.
'''
min = NumericProperty(0)
'''Minimum boundary to use for scrolling.
:attr:`min` is a :class:`~kivy.properties.NumericProperty` and defaults to
0.
'''
max = NumericProperty(0)
'''Maximum boundary to use for scrolling.
:attr:`max` is a :class:`~kivy.properties.NumericProperty` and defaults to
0.
'''
scroll = NumericProperty(0)
'''Computed value for scrolling. This value is different from
:py:attr:`kivy.effects.kinetic.KineticEffect.value`
in that it will return to one of the min/max bounds.
:attr:`scroll` is a :class:`~kivy.properties.NumericProperty` and defaults
to 0.
'''
overscroll = NumericProperty(0)
'''Computed value when the user over-scrolls i.e. goes out of the bounds.
:attr:`overscroll` is a :class:`~kivy.properties.NumericProperty` and
defaults to 0.
'''
target_widget = ObjectProperty(None, allownone=True, baseclass=Widget)
'''Widget to attach to this effect. Even if this class doesn't make changes
to the `target_widget` by default, subclasses can use it to change the
graphics or apply custom transformations.
:attr:`target_widget` is a :class:`~kivy.properties.ObjectProperty` and
defaults to None.
'''
displacement = NumericProperty(0)
'''Cumulative distance of the movement during the interaction. This is used
to determine if the movement is a drag (more than :attr:`drag_threshold`)
or not.
:attr:`displacement` is a :class:`~kivy.properties.NumericProperty` and
defaults to 0.
'''
def reset(self, pos):
'''(internal) Reset the value and the velocity to the `pos`.
Mostly used when the bounds are checked.
'''
self.value = pos
self.velocity = 0
if self.history:
val = self.history[-1][1]
self.history = [(time(), val)]
def on_value(self, *args):
scroll_min = self.min
scroll_max = self.max
if scroll_min > scroll_max:
scroll_min, scroll_max = scroll_max, scroll_min
if self.value < scroll_min:
self.overscroll = self.value - scroll_min
self.reset(scroll_min)
elif self.value > scroll_max:
self.overscroll = self.value - scroll_max
self.reset(scroll_max)
else:
self.scroll = self.value
def start(self, val, t=None):
self.is_manual = True
self.displacement = 0
return super(ScrollEffect, self).start(val, t)
def update(self, val, t=None):
self.displacement += abs(val - self.history[-1][1])
return super(ScrollEffect, self).update(val, t)
def stop(self, val, t=None):
self.is_manual = False
self.displacement += abs(val - self.history[-1][1])
if self.displacement <= self.drag_threshold:
self.velocity = 0
return
return super(ScrollEffect, self).stop(val, t)