Version

Quick search

Table Of Contents

Source code for kivy.effects.scroll

'''
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


[docs]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. '''
[docs] 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
[docs] def start(self, val, t=None): self.is_manual = True self.displacement = 0 return super(ScrollEffect, self).start(val, t)
[docs] def update(self, val, t=None): self.displacement += abs(val - self.history[-1][1]) return super(ScrollEffect, self).update(val, t)
[docs] 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)