U
    Pea                     @   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mZmZmZmZmZmZ G d
d deZedkrddlmZ G dd deZe   dS )a  
Carousel
========

.. image:: images/carousel.gif
    :align: right

.. versionadded:: 1.4.0

The :class:`Carousel` widget provides the classic mobile-friendly carousel view
where you can swipe between slides.
You can add any content to the carousel and have it move horizontally or
vertically. The carousel can display pages in a sequence or a loop.

Example::

    from kivy.app import App
    from kivy.uix.carousel import Carousel
    from kivy.uix.image import AsyncImage


    class CarouselApp(App):
        def build(self):
            carousel = Carousel(direction='right')
            for i in range(10):
                src = "http://placehold.it/480x270.png&text=slide-%d&.png" % i
                image = AsyncImage(source=src, fit_mode="contain")
                carousel.add_widget(image)
            return carousel


    CarouselApp().run()


Kv Example::

    Carousel:
        direction: 'right'
        AsyncImage:
            source: 'http://placehold.it/480x270.png&text=slide-1.png'
        AsyncImage:
            source: 'http://placehold.it/480x270.png&text=slide-2.png'
        AsyncImage:
            source: 'http://placehold.it/480x270.png&text=slide-3.png'
        AsyncImage:
            source: 'http://placehold.it/480x270.png&text=slide-4.png'


.. versionchanged:: 1.5.0
    The carousel now supports active children, like the
    :class:`~kivy.uix.scrollview.ScrollView`. It will detect a swipe gesture
    according to the :attr:`Carousel.scroll_timeout` and
    :attr:`Carousel.scroll_distance` properties.

    In addition, the slide container is no longer exposed by the API.
    The impacted properties are
    :attr:`Carousel.slides`, :attr:`Carousel.current_slide`,
    :attr:`Carousel.previous_slide` and :attr:`Carousel.next_slide`.

)Carousel    )partial)Clock)Factory)	Animation)StencilView)RelativeLayout)BooleanPropertyOptionPropertyAliasPropertyNumericPropertyListPropertyObjectPropertyStringPropertyc                       s  e Zd ZdZeg Zdd ZeeddZe	dddZ
ed	Zed
ZedZedZdd Zdd ZeeedddZdd ZeedddZdd ZeedddZdd ZeedddZedZedZedZedZeddd Ze d!dd Z!e d!dd Z"e d!dd Z#edZ$e d!dd Z%d!Z& fd"d#Z'd$d% Z(d&d' Z)dRd)d*Z*d+d, Z+e,d-d. Z-dS fd/d0	Z.d1d2 Z/d3d4 Z0d5d6 Z1d7d8 Z2d9d: Z3d;d< Z4d=d> Z5dTd@dAZ6 fdBdCZ7 fdDdEZ8 fdFdGZ9 fdHdIZ: fdJdKZ;dU fdLdM	Z< fdNdOZ=dV fdPdQ	Z>  Z?S )Wr   zCCarousel class. See module documentation for more information.
    c                 C   s   dd | j D S )Nc                 S   s   g | ]
}|j qS  parent.0xr   r   5/tmp/pip-unpacked-wheel-xzebddm3/kivy/uix/carousel.py
<listcomp>W   s     z2Carousel._get_slides_container.<locals>.<listcomp>slidesselfr   r   r   _get_slides_containerV   s    zCarousel._get_slides_containerr   )bindright)r   lefttopbottom)optionsg?g      ?g333333?Fc                 C   s   | j r| jt| j  S d S N)r   _indexlenr   r   r   r   
_get_index   s    zCarousel._get_indexc                 C   s"   | j r|t| j  | _nd | _d S r#   )r   r%   r$   )r   valuer   r   r   
_set_index   s    zCarousel._set_index)r$   r   T)r   cachec                 C   sN   | j }t|}| j}|dk r d S | jr6|dkr6|d S |dkrJ||d  S d S )N   r      )r   r%   indexloop)r   r   
len_slidesr-   r   r   r   _prev_slide   s    zCarousel._prev_slide)r   r-   r.   c                 C   s   t | jr| j| jpd S d S Nr   )r%   r   r-   r   r   r   r   _curr_slide   s    
zCarousel._curr_slide)r   r-   c                 C   s^   t | jdk rd S | jr6| jt | jd kr6| jd S | jt | jd k rZ| j| jd  S d S )Nr*   r,   r   )r%   r   r.   r-   r   r   r   r   _next_slide   s    
zCarousel._next_slide   Z20dpZout_quadr   )Z	allownoneNc                    sL   t  jd _tt jf | d  _d _d _	 
d fdd d S )Nr+   Fr.   c                     s      S r#   )_insert_visible_slides)argsr   r   r   <lambda>      z#Carousel.__init__.<locals>.<lambda>)r   Zcreate_trigger_position_visible_slides _trigger_position_visible_slidessuperr   __init___skip_slidetouch_mode_change_prioritize_nextZfbind)r   kwargs	__class__r   r   r<     s     zCarousel.__init__c                 C   sr   | j }|| j|| }}||kr*dS || _||krTd| _| j|d |   nd| _| j|d |   dS )z`Animate to the slide that is passed as the argument.

        .. versionchanged:: 1.8.0
        NT)r3   F)r0   )r   r-   current_slider=   r?   r5   	load_nextload_previous)r   slider   startstopr   r   r   
load_slide!  s    
zCarousel.load_slidec                 C   s   | j dd dS )zHAnimate to the previous slide.

        .. versionadded:: 1.7.0
        prev)modeN)rD   r   r   r   r   rE   5  s    zCarousel.load_previousnextc                 C   s`   | j dk	r\| j\}}| d |d |d | d d}|| j }|dkrN| }| jd|d dS )zDAnimate to the next slide.

        .. versionadded:: 1.7.0
        Nr*   )r    r!   r   r   rJ   r   )min_moveoffset)r-   size	direction_start_animation)r   rK   whZ
_direction_offsetr   r   r   rD   <  s    


zCarousel.load_nextc                 C   s   |j S r#   r   )r   rF   r   r   r   get_slide_containerN  s    zCarousel.get_slide_containerc                 C   s   | j ot| jdkS )Nr*   )r.   r%   r   r   r   r   r   _prev_equals_nextQ  s    zCarousel._prev_equals_nextc           	         s  | j }|r|n| j}|r$||| _nd | _| j}|r@||| _nd | _|rN|n| j}|rd||| _nd | _| jrt| | j	r~dndd  t
t| j}| jD ]}|| q| jr| jj| k	rt
t| | j | jr| jj| k	rt
t| | j | jrt
t| | j d S )N_prev_next)rU   previous_sliderW   rC   _current
next_sliderX   rV   setattrr?   r;   r   remove_widgetslides_containerr   
add_widget)	r   r3   r0   rU   rY   rC   r[   Zsuper_remove	containerrA   r   r   r5   U  s0    

zCarousel._insert_visible_slidesc                 G   s  | j | j }}t|d }|s"d S | j| j| j| jf\}}}}| j| jd  }	}
| j	| j
| j  }}}| j}||d }||d }d}| j}|
dkr||	 }|| || d}|| || d}|r||
 |f|_nP|r(|r(|dkr(|	dkr|
dks|	dk r(|
dkr(||
 |f|_d	}|r8||f|_|rBd S |rX||
 |f|_nL|r|r||kr|	dk r|
dks|	dkr|
dkr||
 |f|_|
d
kr||	 }|| || d}|| || d}|r|||
 f|_nP|r@|r@|dkr@|	dkr|
dks.|	dk r@|
dkr@|||
 f|_d	}|rP||f|_|rZd S |rp|||
 f|_nL|r|r||kr|	dk r|
dks|	dkr|
dkr|||
 f|_d S )Nr,   r   r+   Frl)lrrc   rb   Ttb)tbre   rf   )r   r-   r%   r   ywidthheightrT   rP   rW   rX   rZ   rU   r.   pos)r   r6   r   r-   Zno_of_slidesr   rg   rh   ri   rT   rP   rW   rX   rZ   rU   Z
last_slideZfirst_slideZ	skip_nextZ_loopZxoffZx_prevZx_nextZyoffZy_prevZy_nextr   r   r   r9   x  s    



z!Carousel._position_visible_slidesc                 G   s$   | j }| jD ]
}||_ q|   d S r#   )rO   r^   r:   )r   r6   rO   rF   r   r   r   on_size  s    
zCarousel.on_sizec                 G   s   |    d S r#   )r:   r   r6   r   r   r   on_pos  s    zCarousel.on_posc                 G   s   |    |   d| _d S r1   )r5   r:   rT   rl   r   r   r   on_index  s    zCarousel.on_indexc                 G   s,   | j r| jt| j  | _|   |   d S r#   )r   r-   r%   r5   r:   rl   r   r   r   	on_slides  s    zCarousel.on_slidesc                 G   sD  |    | jd }| j}| j}| j}| j}| jd k	s<|d kr@d S |dkrR|| ks|dkrb||ks|dkrt|| ks|dkr||kr| jr|  jd7  _n|dkr||ks|dkr|| ks|dkr||ks|dkr|| kr| jr|  jd8  _nL| j	r@|dk |dkk}| j
|k	r@|| _
|| jd kkr@| j| j | _| _d S )Nr   rc   rb   re   rf   r,   rt)r:   rP   rT   rh   ri   r-   r=   r[   rY   rV   r?   rX   rW   )r   r6   rP   rT   rh   ri   r-   	new_valuer   r   r   
on__offset  sX    
zCarousel.on__offsetc                    s4  d}| d jd }|dk}|r( jn j}| d j}| d j}|||  k r`| }n||| krp|} j}	|dkr j}	t j	}
 j
} jr|
dkr|dk}||
d k}|dkr|dk}|dk }n|dk }|dk}|r|s|r|rd}t||	 jd}|   fd	d
}|j|d |  d S )Nr   rP   ra   rM   rN   r,   rp   )rT   dre   c                     s    j d k	r j  _d  _ d S r#   )r=   r-   )rb   r   r   r   _cmp  s    
z'Carousel._start_animation.<locals>._cmp)Zon_complete)getrP   rh   ri   rM   rT   anim_move_durationanim_cancel_durationr%   r   r-   r.   r   	anim_type
cancel_allr   rG   )r   r6   r@   Z
new_offsetrP   Zis_horizontalZextentrM   rT   Zdurr/   r-   Zis_firstZis_lastZtowards_prevZtowards_nextZanimrt   r   r   r   rQ     s<    


zCarousel._start_animationsvc                 C   s   d || jS )Nz{0}.{1})formatuid)r   prefixr   r   r   _get_uid  s    zCarousel._get_uidc                    s   | j |j s d|j| d< d S | jr*dS | jr@tt| |S t	
|  || _|  }||  d|jd|j|< t| j| jd | _d| _dS )NTcavoidunknown)rK   timeg     @@F)Zcollide_pointrj   udr~   disabled_touchr;   r   on_touch_downr   ry   ZgrabZ
time_startr   schedule_once_change_touch_modescroll_timeout_change_touch_mode_evr>   )r   touchr|   rA   r   r   r     s(    

 zCarousel.on_touch_downc                    s  | j s| jrR| jdkrRt|j|j | jk rt|j|j | jkr| 	  d| _ nJ| jr| jdkrt|j|j | jk rt|j|j | jkr| 	  d| _ | 
d|jkrd S | j|k	rtt| | | 
 |jkS |j| k	rdS |j| 
  }| jd }|d dkrf|dkr(t|j|j }nt|j|j }|| jkr| j}|d k	r\|  d	|d< n4|dkr|  j|j7  _|d
kr|  j|j7  _dS )N)r    r!   T)r   r   r   r   rK   r   ra   Zscrollrd   )r>   ignore_perpendicular_swipesrP   absZoyrg   scroll_distanceZoxr   r   r~   r   r   r;   r   on_touch_movegrab_currentr   cancelrT   ZdxZdy)r   r   r   rP   ZdistanceevrA   r   r   r   .  sL    







zCarousel.on_touch_movec                    s   |  d|jkrd S | dd |jD kr||  d | _|j|    }|d dkr| j}|d k	rh|  tt| 	| t
t| j|d q|   n&| j|k	r| j|jkrtt| | |   |jkS )Nr   c                 S   s   g | ]
}| qS r   r   r   r   r   r   r   Z  s     z(Carousel.on_touch_up.<locals>.<listcomp>rK   r   g?)r~   r   	grab_listungrabr   r   r   r;   r   r   r   r   r   _do_touch_uprQ   r|   on_touch_up)r   r   r   r   rA   r   r   r   W  s     

zCarousel.on_touch_upc                    s\   t t| | |jd d  D ]2}|j| | }|s:q||_t t| | qd |_d S r#   )r;   r   r   r   remover   )r   r   largsr   rA   r   r   r   l  s    zCarousel._do_touch_upc                    s^   | j s
d S |   |  }| j }|j| }|d dkrZ||  d | _ tt| | d S d S )NrK   r   )r   rQ   r~   r   r   r;   r   r   )r   r   r|   r   r   rA   r   r   r   x  s    

zCarousel._change_touch_modec                    sp   t | j| j| j | jd}|| tt| j||f|| |dkr`| j	|t
| j | n| j| d S )N)rO   r   rg   r   )r   rO   r   rh   rg   r_   r;   r   r   insertr%   append)r   widgetr-   r6   r@   r`   rA   r   r   r_     s     
 
zCarousel.add_widgetc                    s   | j }||krf| j||kr0td| jd | _|j}|| tt| j|f|| || d S tt| j|f|| d S )Nr   r,   )r   r-   maxr   r   r;   r   r]   )r   r   r6   r@   r   r`   rA   r   r   r]     s    

zCarousel.remove_widgetc                    s@   |d kr| j d d  }| j}|D ]}|| q tt|   d S r#   )r   r]   r;   r   clear_widgets)r   childrenr6   r@   r]   r   rA   r   r   r     s    
zCarousel.clear_widgets)rL   )NN)rz   )r   )N)@__name__
__module____qualname____doc__r   r   r   r   r^   r
   rP   r   rM   rv   rw   r	   r.   r&   r(   r-   r0   rY   r2   rC   r3   r[   r   r   r   rx   r   r$   r   rW   rZ   rX   rT   r   r   r<   rI   rE   rD   rU   propertyrV   r5   r9   rk   rm   rn   ro   rr   rQ   r~   r   r   r   r   r   r_   r]   r   __classcell__r   r   rA   r   r   J   s   			
	

#<"-
)
r   __main__)Appc                   @   s   e Zd Zdd ZdS )Example1c                 C   s>   t ddd}tdD ]$}d| }tj|dd}|| q|S )Nr   T)rP   r.      z2http://placehold.it/480x270.png&text=slide-%d&.pngZcontain)sourceZfit_mode)r   ranger   Z
AsyncImager_   )r   Zcarouselisrcimager   r   r   build  s    zExample1.buildN)r   r   r   r   r   r   r   r   r     s   r   N)r   __all__	functoolsr   Z
kivy.clockr   Zkivy.factoryr   Zkivy.animationr   Zkivy.uix.stencilviewr   Zkivy.uix.relativelayoutr   Zkivy.propertiesr	   r
   r   r   r   r   r   r   r   Zkivy.appr   r   runr   r   r   r   <module>   s"   =$    c