This file is indexed.

/usr/share/pyshared/kivy/effects/kinetic.py is in python-kivy 1.7.2-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
'''
Kinetic effect
==============

.. versionadded:: 1.7.0

The :class:`KineticEffect` is the base class that is used to compute the
velocity out of a movement. When the movement is finished, the effect will
compute the position of the movement according to the velocity, and reduce the
velocity with a friction. The movement stop until the velocity is 0.

Conceptually, the usage could be::

    >>> effect = KineticEffect()
    >>> effect.start(10)
    >>> effect.update(15)
    >>> effect.update(30)
    >>> effect.stop(48)

Over the time, you will start a movement of a value, update it, and stop the
movement. At this time, you'll get the movement value into
:data:`KineticEffect.value`. On the example i've typed manually, the computed
velocity will be::

    >>> effect.velocity
    3.1619100231163046

After multiple clock interaction, the velocity will decrease according to
:data:`KineticEffect.friction`. The computed value will be stored in
:data:`KineticEffect.value`. The output of this `value` could be::

    46.30038145219605
    54.58302451968686
    61.9229016256196
    # ...

'''

__all__ = ('KineticEffect', )


from time import time
from kivy.event import EventDispatcher
from kivy.properties import NumericProperty, BooleanProperty
from kivy.clock import Clock


class KineticEffect(EventDispatcher):
    '''Kinetic effect class. See module documentation for more information.
    '''

    velocity = NumericProperty(0)
    '''Velocity of the movement.

    :data:`velocity` is a :class:`~kivy.properties.NumericProperty`, default to
    0
    '''

    friction = NumericProperty(0.05)
    '''Friction to apply on the velocity

    :data:`velocity` is a :class:`~kivy.properties.NumericProperty`, default to
    0.05
    '''

    value = NumericProperty(0)
    '''Value (during the movement and computed) of the effect.

    :data:`velocity` is a :class:`~kivy.properties.NumericProperty`, default to
    0
    '''

    is_manual = BooleanProperty(False)
    '''Indicate if a movement is in progress (True) or not (False).

    :data:`velocity` is a :class:`~kivy.properties.BooleanProperty`, default to
    False
    '''

    max_history = NumericProperty(5)
    '''Save up to `max_history` movement value into the history. This is used
    for correctly calculating the velocity according to the movement.

    :data:`max_history` is a :class:`~kivy.properties.NumericProperty`, default
    to 5.
    '''

    def __init__(self, **kwargs):
        self.history = []
        self.trigger_velocity_update = Clock.create_trigger(self.update_velocity, 0)
        super(KineticEffect, self).__init__(**kwargs)

    def apply_distance(self, distance):
        if abs(distance) < 0.1:
            self.velocity = 0
        self.value += distance

    def start(self, val, t=None):
        '''Start the movement.

        :Parameters:
            `val`: float or int
                Value of the movement
            `t`: float, default to None
                Time when the movement happen. If no time is set, it will use
                time.time()
        '''
        self.is_manual = True
        t = t or time()
        self.velocity = 0
        self.history = [(t, val)]

    def update(self, val, t=None):
        '''Update the movement.

        See :meth:`start` for the arguments.
        '''
        t = t or time()
        distance = val - self.history[-1][1]
        self.apply_distance(distance)
        self.history.append((t, val))
        if len(self.history) > self.max_history:
            self.history.pop(0)

    def stop(self, val, t=None):
        '''Stop the movement.

        See :meth:`start` for the arguments.
        '''
        self.is_manual = False
        t = t or time()
        distance = val - self.history[-1][1]
        self.apply_distance(distance)
        newest_sample = (t, val)
        old_sample = self.history[0]
        for sample in self.history:
            if (newest_sample[0] - sample[0]) < 10. / 60.:
                break
            old_sample = sample
        distance = newest_sample[1] - old_sample[1]
        duration = abs(newest_sample[0] - old_sample[0])
        self.velocity = (distance / max(duration, 0.0001))
        self.trigger_velocity_update()

    def cancel(self):
        '''Cancel a movement. This can be used in case of :meth:`stop` cannot be
        called. It will reset :data:`is_manual` to False, and compute the
        movement if the velocity is > 0.
        '''
        self.is_manual = False
        self.trigger_velocity_update()

    def update_velocity(self, dt):
        '''(internal) Update the velocity according to a frametime and the
        friction.
        '''
        if abs(self.velocity) <= 0.5:
            self.velocity = 0
            return

        self.velocity -= self.velocity * self.friction
        self.apply_distance(self.velocity * dt)
        self.trigger_velocity_update()