U
    Pe1$                     @   s|   d Z ddlmZ ddlmZ ddlmZmZ ddlm	Z	 ddl
mZmZ G dd deZG d	d
 d
e	ZG dd deZdS )a4  
RecycleView Layouts
===================

.. versionadded:: 1.10.0

The Layouts handle the presentation of views for the
:class:`~kivy.uix.recycleview.RecycleView`.

.. warning::
    This module is highly experimental, its API may change in the future and
    the documentation is not complete at this time.
    )string_types)Factory)StringPropertyObjectProperty)CompoundSelectionBehavior)RecycleDataViewBehavior_view_base_cachec                   @   s   e Zd ZdS )LayoutChangeExceptionN)__name__
__module____qualname__ r   r   ?/tmp/pip-unpacked-wheel-xzebddm3/kivy/uix/recycleview/layout.pyr	      s   r	   c                       s   e Zd ZdZedddZg Zi Z fddZ fddZ	d	d
 Z
dd Z fddZ fddZ fddZdd Z fddZ  ZS )LayoutSelectionBehaviora  The :class:`LayoutSelectionBehavior` can be combined with
    :class:`RecycleLayoutManagerBehavior` to allow its derived classes
    selection behaviors similarly to how
    :class:`~kivy.uix.behaviors.compoundselection.CompoundSelectionBehavior`
    can be used to add selection behaviors to normal layout.

    :class:`RecycleLayoutManagerBehavior` manages its children
    differently than normal layouts or widgets so this class adapts
    :class:`~kivy.uix.behaviors.compoundselection.CompoundSelectionBehavior`
    based selection to work with :class:`RecycleLayoutManagerBehavior` as well.

    Similarly to
    :class:`~kivy.uix.behaviors.compoundselection.CompoundSelectionBehavior`,
    one can select using the keyboard or touch, which calls :meth:`select_node`
    or :meth:`deselect_node`, or one can call these methods directly. When a
    item is selected or deselected :meth:`apply_selection` is called. See
    :meth:`apply_selection`.


    NTZ	allownonec                    s   d| _ tt| jf | d S NF)Znodes_order_reversedsuperr   __init__)selfkwargs	__class__r   r   r   B   s    z LayoutSelectionBehavior.__init__c                    s\   | j   d krg  }| _n fddt|D  }| _dd t|D | _tt| ||S )Nc                    s   g | ]\}}|  r|qS r   )get).0idkeyr   r   
<listcomp>M   s    
 zCLayoutSelectionBehavior.compute_sizes_from_data.<locals>.<listcomp>c                 S   s   i | ]\}}||qS r   r   )r   kvr   r   r   
<dictcomp>P   s      zCLayoutSelectionBehavior.compute_sizes_from_data.<locals>.<dictcomp>)key_selection_selectable_nodes	enumerate
_nodes_mapr   r   compute_sizes_from_data)r   dataflagsZnodesr   r   r   r&   F   s    

 z/LayoutSelectionBehavior.compute_sizes_from_datac                 C   s   | j S N)r#   )r   r   r   r   get_selectable_nodesT   s    z,LayoutSelectionBehavior.get_selectable_nodesc                 C   s
   | j | S r)   )r%   )r   nodeZselectable_nodesr   r   r   get_index_of_nodeX   s    z)LayoutSelectionBehavior.get_index_of_nodec                    s2   t t| |||\}}||k	r*| | ||fS r)   )r   r   	goto_node	goto_view)r   r   Z	last_nodeZlast_node_idxr+   idxr   r   r   r-   \   s    
  
z!LayoutSelectionBehavior.goto_nodec                    s8   t t| |r4| jj|}|d k	r4| ||d d S )NT)r   r   select_noderecycleviewview_adapterget_visible_viewapply_selectionr   r+   viewr   r   r   r0   c   s    z#LayoutSelectionBehavior.select_nodec                    s8   t t| |r4| jj|}|d k	r4| ||d d S r   )r   r   deselect_noder1   r2   r3   r4   r5   r   r   r   r7   i   s    z%LayoutSelectionBehavior.deselect_nodec                 C   s8   |j }|tkrt|tt|< t| r4|| j|| dS )ao  Applies the selection to the view. This is called internally when
        a view is displayed and it needs to be shown as selected or as not
        selected.

        It is called when :meth:`select_node` or :meth:`deselect_node` is
        called or when a view needs to be refreshed. Its function is purely to
        update the view to reflect the selection state. So the function may be
        called multiple times even if the selection state may not have changed.

        If the view is a instance of
        :class:`~kivy.uix.recycleview.views.RecycleDataViewBehavior`, its
        :meth:`~kivy.uix.recycleview.views.RecycleDataViewBehavior.apply_selection` method will be called every time the view needs to refresh
        the selection state. Otherwise, the this method is responsible
        for applying the selection.

        :Parameters:

            `index`: int
                The index of the data item that is associated with the view.
            `view`: widget
                The widget that is the view of this data item.
            `is_selected`: bool
                Whether the item is selected.
        N)r   r   
isinstancer   r4   r1   )r   indexr6   Zis_selected	viewclassr   r   r   r4   o   s    z'LayoutSelectionBehavior.apply_selectionc                    s.   t t| |||| | |||| jk d S r)   )r   r   refresh_view_layoutr4   Zselected_nodesr   r9   Zlayoutr6   viewportr   r   r   r;      s    
   z+LayoutSelectionBehavior.refresh_view_layout)r
   r   r   __doc__r   r"   r#   r%   r   r&   r*   r,   r-   r0   r7   r4   r;   __classcell__r   r   r   r   r      s   "r   c                   @   s   e Zd ZdZedZedZedddZdZ	dd Z
dd Zd	d
 Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )RecycleLayoutManagerBehaviora  A RecycleLayoutManagerBehavior is responsible for positioning views into
    the :attr:`RecycleView.data` within a :class:`RecycleView`. It adds new
    views into the data when it becomes visible to the user, and removes them
    when they leave the visible area.
    NTr   c                 C   sH   || _ |rD| j}|d|j |d|j |d|jd |d|jd d S Nr:   key_viewclass)r1   fbindrefresh_from_data_dispatch_prop_on_source)r   rvrC   r   r   r   attach_recycleview   s    z/RecycleLayoutManagerBehavior.attach_recycleviewc                 C   sV   |    | j}|rL| j}|d|j |d|j |d|jd |d|jd d | _d S rA   )clear_layoutr1   funbindrD   rE   )r   rF   rI   r   r   r   detach_recycleview   s    z/RecycleLayoutManagerBehavior.detach_recycleviewc                 C   s   d S r)   r   r   r'   r(   r   r   r   r&      s    z4RecycleLayoutManagerBehavior.compute_sizes_from_datac                 C   s   d S r)   r   rK   r   r   r   compute_layout   s    z+RecycleLayoutManagerBehavior.compute_layoutc                 C   s   dS z<`viewport` is in coordinates of the layout manager.
        Nr   )r   r'   r=   r   r   r   compute_visible_views   s    z2RecycleLayoutManagerBehavior.compute_visible_viewsc                 C   s   dS rM   r   )r   indicesr'   r=   r   r   r   set_visible_views   s    z.RecycleLayoutManagerBehavior.set_visible_viewsc                 C   s   | j j|||| dS )zY`See :meth:`~kivy.uix.recycleview.views.RecycleDataAdapter.refresh_view_layout`.
        N)r1   r2   r;   r<   r   r   r   r;      s       z0RecycleLayoutManagerBehavior.refresh_view_layoutc                 C   s   dS )zyReturn the view `index` on which position, `pos`, falls.

        `pos` is in coordinates of the layout manager.
        Nr   )r   posr   r   r   get_view_index_at   s    z.RecycleLayoutManagerBehavior.get_view_index_atc                 C   s    | j }|r|j}|r|  d S r)   )r1   r2   Zmake_views_dirtyr   rF   adapterr   r   r   remove_views   s
    z)RecycleLayoutManagerBehavior.remove_viewsc                 C   s$   | j }|r |j}|r ||| d S r)   )r1   r2   Zmake_view_dirty)r   r6   r9   rF   rT   r   r   r   remove_view   s
    z(RecycleLayoutManagerBehavior.remove_viewc                 C   s    | j }|r|j}|r|  d S r)   )r1   r2   Z
invalidaterS   r   r   r   rH      s
    z)RecycleLayoutManagerBehavior.clear_layoutc                 C   s   dS )zVMoves the views so that the view corresponding to `index` is
        visible.
        Nr   )r   r9   r   r   r   r.      s    z&RecycleLayoutManagerBehavior.goto_viewc                 C   s   t |trtt|| _d S r)   )r8   r   getattrr   r:   )r   instancevaluer   r   r   on_viewclass   s    
z)RecycleLayoutManagerBehavior.on_viewclass)r
   r   r   r>   r   r:   r   rB   r1   Zasked_sizesrG   rJ   r&   rL   rN   rP   r;   rR   rU   rV   rH   r.   rZ   r   r   r   r   r@      s$   r@   N)r>   Zkivy.compatr   Zkivy.factoryr   Zkivy.propertiesr   r   Zkivy.uix.behaviorsr   Zkivy.uix.recycleview.viewsr   r   	Exceptionr	   r   objectr@   r   r   r   r   <module>   s   }