<commit_before>'''
Scroll View
===========

.. versionadded:: 1.0.4

The :class:`ScrollView` widget provides a scrollable/pannable viewport that is
clipped at the scrollview's bounding box.

Scrolling Behavior
------------------

ScrollView accepts only one child, and applies a viewport/window to it
according to the :data:`scroll_x` and :data:`scroll_y` properties. Touches are
analyzed to determine if the user wants to scroll or control the child in some
other manner - you cannot do both at the same time. To determine if interaction
is a scrolling gesture, these properties are used:

    - :data:`ScrollView.scroll_distance` a minimum distance to travel, default
      to 20 pixels.
    - :data:`ScrollView.scroll_timeout` a maximum time period, default to 250
      milliseconds.

If a touch travels :data:`~ScrollView.scroll_distance` pixels within the
:data:`~ScrollView.scroll_timeout` period, it is recognized as a scrolling
gesture and translatation (scroll/pan) will begin. If the timeout occurs, the
touch down event is dispatched to the child instead (no translation).

.. versionadded:: 1.1.1

    Scrollview now animates scrolling in Y when a mousewheel is used.

Limiting to X or Y Axis
-----------------------

By default, ScrollView allows scrolling in both the X and Y axes. You can
explicitly disable scrolling on an axis by setting
:data:`ScrollView.do_scroll_x` or :data:`ScrollView.do_scroll_y` to False.

Managing the Content Size
-------------------------

ScrollView manages the position of the child content, not the size. You must
carefully specify the :data:`ScrollView.size_hint` property to get the desired
scroll/pan effect.

By default, size_hint is (1, 1), so the content size will fit your ScrollView
exactly (you will have nothing to scroll). You must deactivate at least one of
the size_hint instructions (x or y) of the child to enable scrolling.

To scroll a :class:`GridLayout` on Y-axis/vertically, set the child's width
identical to that of the ScrollView (size_hint_x=1, default), and set the
size_hint_y property to None::

    layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
    #Make sure the height is such that there is something to scroll.
    layout.bind(minimum_height=layout.setter('height'))
    for i in range(30):
        btn = Button(text=str(i), size_hint_y=None, height=40)
        layout.add_widget(btn)
    root = ScrollView(size_hint=(None, None), size=(400, 400))
    root.add_widget(layout)

Controlling Timeout, Distance and Trigger
-----------------------------------------

.. versionadded:: 1.0.8

In your configuration file, you can some default values for this widget::

    [widgets]
    scroll_timeout = 250
    scroll_distance = 20
    scroll_friction = 1.

If you want to reduce the default timeout, you can set::

    [widgets]
    scroll_timeout = 150

'''

__all__ = ('ScrollView', )

from functools import partial
from kivy.animation import Animation
from kivy.config import Config
from kivy.clock import Clock
from kivy.uix.stencilview import StencilView
from kivy.properties import NumericProperty, BooleanProperty, AliasProperty, \
        ObjectProperty, ListProperty


# When we are generating documentation, Config doesn't exist
_scroll_timeout = _scroll_distance = _scroll_friction = 0
if Config:
    _scroll_timeout = Config.getint('widgets', 'scroll_timeout')
    _scroll_distance = Config.getint('widgets', 'scroll_distance')
    _scroll_friction = Config.getfloat('widgets', 'scroll_friction')


class ScrollView(StencilView):
    '''ScrollView class. See module documentation for more information.
    '''

    def __init__(self, **kwargs):
        self._touch = False
        self._tdx = self._tdy = self._ts = self._tsn = 0
        self._scroll_y_mouse = 0
        super(ScrollView, self).__init__(**kwargs)
        self.bind(scroll_x=self.update_from_scroll,
                  scroll_y=self.update_from_scroll,
                  pos=self.update_from_scroll,
                  size=self.update_from_scroll)
        self.update_from_scroll()

    def convert_distance_to_scroll(self, dx, dy):
        '''Convert a distance in pixels to a scroll distance, depending on the
        content size and the scrollview size.

        The result will be a tuple of scroll distance that can be added to<commit_msg>scrollview: fix initial mousewheel scrolling. closes #645<commit_after>'''
Scroll View
===========

.. versionadded:: 1.0.4

The :class:`ScrollView` widget provides a scrollable/pannable viewport that is
clipped at the scrollview's bounding box.

Scrolling Behavior
------------------

ScrollView accepts only one child, and applies a viewport/window to it
according to the :data:`scroll_x` and :data:`scroll_y` properties. Touches are
analyzed to determine if the user wants to scroll or control the child in some
other manner - you cannot do both at the same time. To determine if interaction
is a scrolling gesture, these properties are used:

    - :data:`ScrollView.scroll_distance` a minimum distance to travel, default
      to 20 pixels.
    - :data:`ScrollView.scroll_timeout` a maximum time period, default to 250
      milliseconds.

If a touch travels :data:`~ScrollView.scroll_distance` pixels within the
:data:`~ScrollView.scroll_timeout` period, it is recognized as a scrolling
gesture and translatation (scroll/pan) will begin. If the timeout occurs, the
touch down event is dispatched to the child instead (no translation).

.. versionadded:: 1.1.1

    Scrollview now animates scrolling in Y when a mousewheel is used.

Limiting to X or Y Axis
-----------------------

By default, ScrollView allows scrolling in both the X and Y axes. You can
explicitly disable scrolling on an axis by setting
:data:`ScrollView.do_scroll_x` or :data:`ScrollView.do_scroll_y` to False.

Managing the Content Size
-------------------------

ScrollView manages the position of the child content, not the size. You must
carefully specify the :data:`ScrollView.size_hint` property to get the desired
scroll/pan effect.

By default, size_hint is (1, 1), so the content size will fit your ScrollView
exactly (you will have nothing to scroll). You must deactivate at least one of
the size_hint instructions (x or y) of the child to enable scrolling.

To scroll a :class:`GridLayout` on Y-axis/vertically, set the child's width
identical to that of the ScrollView (size_hint_x=1, default), and set the
size_hint_y property to None::

    layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
    #Make sure the height is such that there is something to scroll.
    layout.bind(minimum_height=layout.setter('height'))
    for i in range(30):
        btn = Button(text=str(i), size_hint_y=None, height=40)
        layout.add_widget(btn)
    root = ScrollView(size_hint=(None, None), size=(400, 400))
    root.add_widget(layout)

Controlling Timeout, Distance and Trigger
-----------------------------------------

.. versionadded:: 1.0.8

In your configuration file, you can some default values for this widget::

    [widgets]
    scroll_timeout = 250
    scroll_distance = 20
    scroll_friction = 1.

If you want to reduce the default timeout, you can set::

    [widgets]
    scroll_timeout = 150

'''

__all__ = ('ScrollView', )

from functools import partial
from kivy.animation import Animation
from kivy.config import Config
from kivy.clock import Clock
from kivy.uix.stencilview import StencilView
from kivy.properties import NumericProperty, BooleanProperty, AliasProperty, \
        ObjectProperty, ListProperty


# When we are generating documentation, Config doesn't exist
_scroll_timeout = _scroll_distance = _scroll_friction = 0
if Config:
    _scroll_timeout = Config.getint('widgets', 'scroll_timeout')
    _scroll_distance = Config.getint('widgets', 'scroll_distance')
    _scroll_friction = Config.getfloat('widgets', 'scroll_friction')


class ScrollView(StencilView):
    '''ScrollView class. See module documentation for more information.
    '''

    def __init__(self, **kwargs):
        self._touch = False
        self._tdx = self._tdy = self._ts = self._tsn = 0
        self._scroll_y_mouse = 1
        super(ScrollView, self).__init__(**kwargs)
        self.bind(scroll_x=self.update_from_scroll,
                  scroll_y=self.update_from_scroll,
                  pos=self.update_from_scroll,
                  size=self.update_from_scroll)
        self.update_from_scroll()

    def convert_distance_to_scroll(self, dx, dy):
        '''Convert a distance in pixels to a scroll distance, depending on the
        content size and the scrollview size.

        The result will be a tuple of scroll distance that can be added to
{'fraction_non_alphanumeric': 0.10057736720554272, 'fraction_numerical': 0.010046189376443419, 'mean_word_length': 3.482919254658385, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7211303', 'n_tokens_mistral': 2522, 'n_tokens_neox': 2363, 'n_words': 937}