U
    P’“ev-  ã                   @   sà   d Z dZddlmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZ dd	lmZ G d
d„ de	ƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZe de¡ e de¡ e de¡ e de¡ dS )ah  
TUIO Input Provider
===================

TUIO is the de facto standard network protocol for the transmission of
touch and fiducial information between a server and a client. To learn
more about TUIO (which is itself based on the OSC protocol), please
refer to http://tuio.org -- The specification should be of special
interest.

Configure a TUIO provider in the config.ini
-------------------------------------------

The TUIO provider can be configured in the configuration file in the
``[input]`` section::

    [input]
    # name = tuio,<ip>:<port>
    multitouchtable = tuio,192.168.0.1:3333

Configure a TUIO provider in the App
------------------------------------

You must add the provider before your application is run, like this::

    from kivy.app import App
    from kivy.config import Config

    class TestApp(App):
        def build(self):
            Config.set('input', 'multitouchscreen1', 'tuio,0.0.0.0:3333')
            # You can also add a second TUIO listener
            # Config.set('input', 'source2', 'tuio,0.0.0.0:3334')
            # Then do the usual things
            # ...
            return
)ÚTuioMotionEventProviderÚTuio2dCurMotionEventÚTuio2dObjMotionEventé    )ÚLogger)Úpartial)Údeque)ÚMotionEventProvider)ÚMotionEventFactory)ÚMotionEvent)Ú	ShapeRectc                       sp   e Zd ZdZi Z‡ fdd„Zedd„ ƒZedd„ ƒZedd	„ ƒZ	d
d„ Z
dd„ Zdd„ Zdd„ Zdd„ Z‡  ZS )r   ag  The TUIO provider listens to a socket and handles some of the incoming
    OSC messages:

        * /tuio/2Dcur
        * /tuio/2Dobj

    You can easily extend the provider to handle new TUIO paths like so::

        # Create a class to handle the new TUIO type/path
        # Replace NEWPATH with the pathname you want to handle
        class TuioNEWPATHMotionEvent(MotionEvent):

            def depack(self, args):
                # In this method, implement 'unpacking' for the received
                # arguments. you basically translate from TUIO args to Kivy
                # MotionEvent variables. If all you receive are x and y
                # values, you can do it like this:
                if len(args) == 2:
                    self.sx, self.sy = args
                    self.profile = ('pos', )
                self.sy = 1 - self.sy
                super().depack(args)

        # Register it with the TUIO MotionEvent provider.
        # You obviously need to replace the PATH placeholders appropriately.
        TuioMotionEventProvider.register('/tuio/PATH', TuioNEWPATHMotionEvent)

    .. note::

        The class name is of no technical importance. Your class will be
        associated with the path that you pass to the ``register()``
        function. To keep things simple, you should name your class after the
        path that it handles, though.
    c                    sæ   t ƒ  ||¡ | d¡}t|ƒdkrXt d¡ t d¡ dtd |¡ƒ }t |¡ d S |d  d¡}t|ƒdkr¦t d¡ t d¡ dtd |¡ƒ }t |¡ d S |d  d¡\| _| _	t
| j	ƒ| _	i | _d | _tƒ | _i | _d S )Nú,r   z-Tuio: Invalid configuration for TUIO providerz1Tuio: Format must be ip:port (eg. 127.0.0.1:3333)z#Tuio: Current configuration is <%s>ú:é   )ÚsuperÚ__init__ÚsplitÚlenr   ÚerrorÚstrÚjoinÚipÚportÚintÚhandlersÚoscidr   Útuio_event_qÚtouches)ÚselfÚdeviceÚargsÚerrZipport©Ú	__class__© ú=/tmp/pip-unpacked-wheel-xzebddm3/kivy/input/providers/tuio.pyr   Z   s*    






z TuioMotionEventProvider.__init__c                 C   s   |t j| < dS )z.Register a new path to handle in TUIO providerN©r   Ú__handlers__©ÚoscpathÚ	classnamer#   r#   r$   Úregisterq   s    z TuioMotionEventProvider.registerc                 C   s   | t jkrt j| = dS )z:Unregister a path to stop handling it in the TUIO providerNr%   r'   r#   r#   r$   Ú
unregisterv   s    
z"TuioMotionEventProvider.unregisterc                 K   s&   | t jkrtd|  ƒ‚t j|  f |ŽS )z%Create a touch event from a TUIO pathzUnknown %s touch path)r   r&   Ú	Exception)r(   Úkwargsr#   r#   r$   Úcreate|   s    
zTuioMotionEventProvider.createc                 C   s€   zddl m} W n  tk
r0   t d¡ ‚ Y nX |ƒ  | _}|j| j| jdd t	j
D ]"}i | j|< | |t| j|ƒ¡ qXdS )zStart the TUIO providerr   )ÚOSCThreadServerz@Please install the oscpy python module to use the TUIO provider.T)ÚdefaultN)Zoscpy.serverr/   ÚImportErrorr   Úinfor   Úlistenr   r   r   r&   r   Úbindr   Ú_osc_tuio_cb)r   r/   Zoscr(   r#   r#   r$   Ústartƒ   s    ÿ

zTuioMotionEventProvider.startc                 C   s   | j  ¡  dS )zStop the TUIO providerN)r   Zstop_all©r   r#   r#   r$   Ústop“   s    zTuioMotionEventProvider.stopc                 C   s8   z| j  ¡ }W n tk
r$   Y dS X |  ||¡ q dS )z4Update the TUIO provider (pop events from the queue)N)r   ÚpopÚ
IndexErrorÚ_update)r   Údispatch_fnÚvaluer#   r#   r$   Úupdate—   s
    zTuioMotionEventProvider.updatec                 G   s   | j  |||g¡ d S ©N)r   Ú
appendleft)r   r(   Úaddressr   r#   r#   r$   r5   £   s    z$TuioMotionEventProvider._osc_tuio_cbc           
      C   s  |\}}}|dkrd S |dkr”|d }|| j | krjtj| | j||dd … ƒ}|| j | |< |d|ƒ n*| j | | }| |dd … ¡ |d|ƒ |dkrþ|}g }	| j | D ],}||kr®| j | | }||	kr®|	 |¡ q®|	D ]}|d|ƒ | j | |j= qàd S )	N)ó   aliveó   setrC   r   é   Úbeginr>   rB   Úend)r   r   r&   r   ÚmoveÚappendÚid)
r   r<   r=   r(   Úcommandr   rI   ÚtouchZalivesZ	to_deleter#   r#   r$   r;   ¦   s6    
  
ÿ

zTuioMotionEventProvider._update)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r&   r   Ústaticmethodr*   r+   r.   r6   r8   r>   r5   r;   Ú__classcell__r#   r#   r!   r$   r   4   s   #


r   c                       sl   e Zd ZdZdZ‡ fdd„Zedd„ ƒZedd„ ƒZedd„ ƒZ	ed	d„ ƒZ
ed
d„ ƒZedd„ ƒZ‡  ZS )ÚTuioMotionEventa´  Abstraction for TUIO touches/fiducials.

    Depending on the tracking software you use (e.g. Movid, CCV, etc.) and its
    TUIO implementation, the TuioMotionEvent object can support multiple
    profiles such as:

        * Fiducial ID: profile name 'markerid', attribute ``.fid``
        * Position: profile name 'pos', attributes ``.x``, ``.y``
        * Angle: profile name 'angle', attribute ``.a``
        * Velocity vector: profile name 'mov', attributes ``.X``, ``.Y``
        * Rotation velocity: profile name 'rot', attribute ``.A``
        * Motion acceleration: profile name 'motacc', attribute ``.m``
        * Rotation acceleration: profile name 'rotacc', attribute ``.r``
    )ÚaÚbÚcÚXÚYÚZÚAÚBÚCÚmÚrc                    sl   |  dd¡ |  dd¡ tƒ j||Ž d| _d| _d| _d| _d| _d| _d| _	d| _
d| _d| _d| _d S )NZis_touchTZtype_idrK   g        )Ú
setdefaultr   r   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   ©r   r   r-   r!   r#   r$   r   Ý   s    zTuioMotionEvent.__init__c                 C   s   | j S r?   )rS   r7   r#   r#   r$   Ú<lambda>î   ó    zTuioMotionEvent.<lambda>c                 C   s   | j S r?   )r\   r7   r#   r#   r$   r`   ï   ra   c                 C   s   | j S r?   )r]   r7   r#   r#   r$   r`   ð   ra   c                 C   s   | j S r?   )rV   r7   r#   r#   r$   r`   ñ   ra   c                 C   s   | j S r?   )rW   r7   r#   r#   r$   r`   ò   ra   c                 C   s   | j S r?   )rX   r7   r#   r#   r$   r`   ó   ra   )rL   rM   rN   rO   Ú	__attrs__r   ÚpropertyÚangleZ	mot_accelZ	rot_accelZxmotZymotZzmotrQ   r#   r#   r!   r$   rR   Ì   s   rR   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )r   zA 2dCur TUIO touch.c                    s  t |ƒdk r2ttt|dd… ƒƒ\| _| _d| _n¾t |ƒdkrzttt|dd… ƒƒ\| _| _| _| _| _	| j | _d| _nvttt|dd… ƒƒ\| _| _| _| _ttt|dd… ƒƒ\| _	}}| j | _d| _| j
d kràtƒ | _
|| j
_|| j
_d	| j | _tƒ  |¡ d S )
Né   r   r   ©Úpos)rg   ÚmovÚmotaccé   é   )rg   rh   ri   ÚshaperD   )r   ÚlistÚmapÚfloatÚsxÚsyÚprofilerV   rW   r\   rl   r   ÚwidthÚheightr   Údepack©r   r   rs   rt   r!   r#   r$   ru   ù   s&    
ÿ
&

zTuio2dCurMotionEvent.depack©rL   rM   rN   rO   ru   rQ   r#   r#   r!   r$   r   ö   s   r   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )r   zA 2dObj TUIO object.
    c                    s  t |ƒdk r(|dd… \| _| _d| _nÌt |ƒdkr‚|d d… \| _| _| _| _| _| _|dd… \| _| _	| _
| j | _d| _nr|d d… \| _| _| _| _| _| _|dd… \| _| _	| _
}}| j | _d	| _| jd krôtƒ | _|| j_|| j_d
| j | _tƒ  |¡ d S )Nre   r   r   rf   é	   é   )Úmarkeridrg   rd   rh   Úrotri   Úrotaccé   )rz   rg   rd   rh   r{   r|   Úaccrl   rD   )r   rp   rq   rr   ZfidrS   rV   rW   rY   r\   r]   rl   r   rs   rt   r   ru   rv   r!   r#   r$   ru     s$    $
$

zTuio2dObjMotionEvent.depackrw   r#   r#   r!   r$   r     s   r   c                       s,   e Zd ZdZ‡ fdd„Z‡ fdd„Z‡  ZS )ÚTuio2dBlbMotionEventzœA 2dBlb TUIO object.
    # FIXME 3d shape are not supported
    /tuio/2Dobj set s i x y a       X Y A m r
    /tuio/2Dblb set s   x y a w h f X Y A m r
    c                    s   t ƒ j||Ž d| _d S )N)rg   rd   rh   r{   r|   r~   rl   )r   r   rr   r_   r!   r#   r$   r   2  s    zTuio2dBlbMotionEvent.__init__c                    sr   |\| _ | _| _| _| _}}}| _| _| _| j | _| jd krVt	ƒ | _|| j_
|| j_d| j | _tƒ  |¡ d S )NrD   )rp   rq   rS   rV   rW   rY   r\   r]   rl   r   rs   rt   r   ru   )r   r   ÚswÚshÚsdr!   r#   r$   ru   6  s    ÿ  

zTuio2dBlbMotionEvent.depack)rL   rM   rN   rO   r   ru   rQ   r#   r#   r!   r$   r   +  s   r   s   /tuio/2Dcurs   /tuio/2Dobjs   /tuio/2DblbZtuioN)rO   Ú__all__Zkivy.loggerr   Ú	functoolsr   Úcollectionsr   Zkivy.input.providerr   Zkivy.input.factoryr	   Zkivy.input.motioneventr
   Zkivy.input.shaper   r   rR   r   r   r   r*   r#   r#   r#   r$   Ú<module>   s$   & *