Corrections to /guide/inputs.rst

This commit is contained in:
Zen-CODE 2013-03-24 15:37:39 -05:00
parent 21affb9fe4
commit 69b1c6190d
1 changed files with 38 additions and 37 deletions

View File

@ -6,26 +6,27 @@ Input architecture
Kivy is able to handle most types of input: mouse, touchscreen, accelerometer, Kivy is able to handle most types of input: mouse, touchscreen, accelerometer,
gyroscope, etc. It handles the native multitouch protocols on the following gyroscope, etc. It handles the native multitouch protocols on the following
platforms: Tuio, WM_Touch, MacMultitouchSupport, MT Protocol A/B, Android. platforms: Tuio, WM_Touch, MacMultitouchSupport, MT Protocol A/B and Android.
The global architecture can be viewed as:: The global architecture can be viewed as::
Input providers -> Motion event -> Post processing -> Dispatch to Window Input providers -> Motion event -> Post processing -> Dispatch to Window
The class for all input events is the The class of all input events is the
:class:`~kivy.input.motionevent.MotionEvent`. From this, there are 2 kinds of :class:`~kivy.input.motionevent.MotionEvent`. It generates 2 kinds of
events: events:
- Touch events: a motion event that contains at least an X and Y position. - Touch events: a motion event that contains at least an X and Y position.
All the touch events are dispatched accross the Widget tree. All the touch events are dispatched across the Widget tree.
- No-touch events: all the rest. For example, the accelerometer is a - No-touch events: all the rest. For example, the accelerometer is a
continuous event, without position. It never starts or stops. These events continuous event, without position. It never starts or stops. These events
are not dispatched accross the Widget tree. are not dispatched across the Widget tree.
A Motion event is generated by an Input Provider. An input provider is A Motion event is generated by an :mod:`Input Provider <kivy.input.providers>`.
responsible for reading the input event from the operating system, the network An Input Provider is responsible for reading the input event from the operating
or even from another application. Several input providers exist, like: system, the network or even from another application. Several input providers
exist, such as:
- :class:`~kivy.input.providers.tuio.TuioMotionEventProvider`: create a - :class:`~kivy.input.providers.tuio.TuioMotionEventProvider`: create a
UDP server and listen for TUIO/OSC messages. UDP server and listen for TUIO/OSC messages.
@ -33,7 +34,7 @@ or even from another application. Several input providers exist, like:
windows API for reading multitouch information and sending it to Kivy. windows API for reading multitouch information and sending it to Kivy.
- :class:`~kivy.input.providers.probesysfs.ProbeSysfsHardwareProbe`: - :class:`~kivy.input.providers.probesysfs.ProbeSysfsHardwareProbe`:
In Linux, iterate over all the hardware connected to the computer, and In Linux, iterate over all the hardware connected to the computer, and
attach a multitouch input provider for each multitouch hardware found. attaches a multitouch input provider for each multitouch device found.
- and much more! - and much more!
When you write an application, you don't need to create an input provider. Kivy When you write an application, you don't need to create an input provider. Kivy
@ -41,7 +42,7 @@ tries to automatically detect available hardware. However, if you want to
support custom hardware, you will need to configure kivy to make it work. support custom hardware, you will need to configure kivy to make it work.
Before the newly-created Motion Event is passed to the user, Kivy applies Before the newly-created Motion Event is passed to the user, Kivy applies
post-processing on the input. Every motion event is analyzed to detect and post-processing to the input. Every motion event is analyzed to detect and
correct faulty input, as well as make meaningful interpretations like: correct faulty input, as well as make meaningful interpretations like:
- Double-tap detection, according to a distance and time threshold - Double-tap detection, according to a distance and time threshold
@ -49,8 +50,8 @@ correct faulty input, as well as make meaningful interpretations like:
- Reducing the amount of generated events if the native touch hardware is - Reducing the amount of generated events if the native touch hardware is
sending events with nearly the same position sending events with nearly the same position
Then, the motion event is dispatched to the Window. As explained at the start, After processing, the motion event is dispatched to the Window. As explained previosuly,
all events are not dispatched to the whole widget tree, the window filters them. not all events are dispatched to the whole widget tree: the window filters them.
For a given event: For a given event:
- if it's only a motion event, it will be dispatched to - if it's only a motion event, it will be dispatched to
@ -83,8 +84,8 @@ The print could output::
.. warning:: .. warning::
Most people mix up the profile's name and the name of the corresponding Many people mix up the profile's name and the name of the corresponding
property. Just because ``'angle'`` is in the available profile doesnt property. Just because ``'angle'`` is in the available profile doesn't
mean that the touch event object will have an ``angle`` property. mean that the touch event object will have an ``angle`` property.
For the ``'pos'`` profile, the properties ``pos``, ``x``, and ``y`` will be For the ``'pos'`` profile, the properties ``pos``, ``x``, and ``y`` will be
@ -99,7 +100,7 @@ profile exists::
print 'The touch angle is', touch.a print 'The touch angle is', touch.a
You can find a list of available profiles in the You can find a list of available profiles in the
:mod:`api-kivy.input.motionevent` documentation. :mod:`~kivy.input.motionevent` documentation.
Touch events Touch events
------------ ------------
@ -110,9 +111,10 @@ evaluates to True. For all touch events, you automatically have the X and Y
positions available, scaled to the Window width and height. In other words, all positions available, scaled to the Window width and height. In other words, all
touch events have the ``'pos'`` profile. touch events have the ``'pos'`` profile.
You must take care about matrix transformation in your touch as soon as you use You must take care of matrix transformation in your touch as soon as you use
a widget with matrix transformation. Some widgets such as Scatter have their own a widget with matrix transformation. Some widgets such as
matrix transformation, meaning the touch must be multiplied by the scatter :class:`~kivy.uix.scatter.Scatter` have their own matrix transformation,
meaning the touch must be multiplied by the scatter
matrix to be able to correctly dispatch touch positions to the Scatter's matrix to be able to correctly dispatch touch positions to the Scatter's
children. children.
@ -125,22 +127,22 @@ children.
- Get coordinate from window space to local space: - Get coordinate from window space to local space:
:meth:`~kivy.uix.widget.Widget.to_widget` :meth:`~kivy.uix.widget.Widget.to_widget`
You must use one of them to get the good coordinate. Let's take the scatter You must use one of them to scale coordinates correctly to the context.
implementation:: Let's look the scatter implementation::
def on_touch_down(self, touch): def on_touch_down(self, touch):
# push the current coordinate, to be able to restore them later. # push the current coordinate, to be able to restore it later
touch.push() touch.push()
# transform the touch coordinate to local space # transform the touch coordinate to local space
touch.apply_transform_2d(self.to_local) touch.apply_transform_2d(self.to_local)
# dispatch the touch as usual to children # dispatch the touch as usual to children
# the coordinate in the touch are now in local space # the coordinate in the touch is now in local space
ret = super(..., self).on_touch_down(touch) ret = super(..., self).on_touch_down(touch)
# whatever is the result, don't forget to pop the transformation # whatever the result, don't forget to pop your transformation
# after the call, the coordinate will be in parent space # after the call, so the coordinate will be back in parent space
touch.pop() touch.pop()
# return the result (depending what you want.) # return the result (depending what you want.)
@ -164,7 +166,7 @@ now, only a :class:`~kivy.input.shape.ShapeRect` can be exposed::
Double tap Double tap
~~~~~~~~~~ ~~~~~~~~~~
The double tap is the action of tapping twice within a time and a distance. A double tap is the action of tapping twice within a time and a distance.
It's calculated by the doubletap post-processing module. You can test if the It's calculated by the doubletap post-processing module. You can test if the
current touch is one of a double tap or not:: current touch is one of a double tap or not::
@ -179,41 +181,41 @@ current touch is one of a double tap or not::
Grabbing touch events Grabbing touch events
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
It's possible for the parent widget to dispatch a touch event to its child It's possible for the parent widget to dispatch a touch event to a child
widget from within ``on_touch_down``, but not from ``on_touch_move`` or widget from within ``on_touch_down``, but not from ``on_touch_move`` or
``on_touch_up``. This can happen in certain scenarios, like when a touch ``on_touch_up``. This can happen in certain scenarios, like when a touch
movement is outside the bounding box of the parent, so the parent decides not to movement is outside the bounding box of the parent, so the parent decides not to
notify its children of the movement. notify its children of the movement.
But you might want to do something ``on_touch_up``. Say you started something on But you might want to do something in ``on_touch_up``. Say you started something in
the down event, like playing a sound, and you'd like to finish things on the up the ``on_touch_down`` event, like playing a sound, and you'd like to finish things
event. Grabbing is what you need. on the ``on_touch_up`` event. Grabbing is what you need.
When you grab a touch, you will always receive the move and up event. But there When you grab a touch, you will always receive the move and up event. But there
are some limitations to grabbing: are some limitations to grabbing:
- You will receive the event at least twice: one time from your parent (the - You will receive the event at least twice: one time from your parent (the
normal event), and one time from the window (grab). normal event), and one time from the window (grab).
- You might receive an event with a grab touch, but not from you: it can be - You might receive an event with a grabbed touch, but not from you: it can be
because the parent has sent the touch to its children, while it was in because the parent has sent the touch to its children while it was in
the grabbed state. the grabbed state.
- The touch coordinate is not translated to your widget space, because the - The touch coordinate is not translated to your widget space because the
touch is coming directly from the Window. It's your job to convert the touch is coming directly from the Window. It's your job to convert the
coordinate to your local space. coordinate to your local space.
Here is an example on how to use grabbing:: Here is an example of how to use grabbing::
def on_touch_down(self, touch): def on_touch_down(self, touch):
if self.collide_point(*touch.pos): if self.collide_point(*touch.pos):
# if the touch is colliding to our widget, let's grab it. # if the touch collides with our widget, let's grab it
touch.grab(self) touch.grab(self)
# and accept the touch. # and accept the touch.
return True return True
def on_touch_up(self, touch): def on_touch_up(self, touch):
# here, you don't check if the touch is colliding or things like that. # here, you don't check if the touch collides or things like that.
# you just need to check if it's a grabbed touch event # you just need to check if it's a grabbed touch event
if touch.grab_current is self: if touch.grab_current is self:
@ -221,9 +223,8 @@ Here is an example on how to use grabbing::
# do something interesting here # do something interesting here
print 'Hello world!' print 'Hello world!'
# don't forget to ungrab ourself, or you might have counter effects # don't forget to ungrab ourself, or you might have side effects
touch.ungrab(self) touch.ungrab(self)
# and accept the last up # and accept the last up
return True return True