U
    d6                     @  s   d Z ddlmZ ddlmZmZmZmZmZm	Z	 ddl
mZ ddlmZmZmZmZmZ ddlmZmZmZ dd	d
gZe	eeeef ZG dd dZG dd	 d	eZddddddd
ZdS )z
Wrapper for the layout.
    )annotations)Dict	GeneratorIterableListOptionalUnion)Buffer   )AnyContainerConditionalContainer	ContainerWindowto_container)BufferControlSearchBufferControl	UIControlLayoutInvalidLayoutErrorwalkc                   @  s  e Zd ZdZdLddddddZd	d
ddZdd
ddZdd
ddZdddddZdddddZ	e
dd
ddZejdddddZe
dd
d d!Zejdddd"d!Ze
dd
d#d$Ze
d%d
d&d'Zd(d
d)d*Zd+d
d,d-Ze
d.d
d/d0Zd	d.d1d2d3Ze
dd
d4d5Ze
dd
d6d7Zdd
d8d9Zdd
d:d;Zdd
d<d=Zd>d
d?d@Zd>d
dAdBZdd
dCdDZdd
dEdFZdGdHdIdJdKZdS )Mr   aL  
    The layout for a prompt_toolkit
    :class:`~prompt_toolkit.application.Application`.
    This also keeps track of which user control is focused.

    :param container: The "root" container for the layout.
    :param focused_element: element to be focused initially. (Can be anything
        the `focus` function accepts.)
    Nr   zFocusableElement | NoneNone)	containerfocused_elementreturnc              
   C  s   t || _g | _i | _i | _|d krlz| jt|   W qv tk
rh } zt	d|W 5 d }~X Y qvX n
| 
| g | _d S )Nz>Invalid layout. The layout does not contain any Window object.)r   r   _stacksearch_links_child_to_parentappendnextfind_all_windowsStopIterationr   focusvisible_windows)selfr   r   e r%   @/tmp/pip-unpacked-wheel-4x_7prb2/prompt_toolkit/layout/layout.py__init__'   s    

zLayout.__init__str)r   c                 C  s   d| j d| jdS )NzLayout(z, current_window=))r   current_windowr#   r%   r%   r&   __repr__I   s    zLayout.__repr__zGenerator[Window, None, None]c                 c  s"   |   D ]}t|tr|V  qdS )zJ
        Find all the :class:`.UIControl` objects in this layout.
        N)r   
isinstancer   )r#   itemr%   r%   r&   r   L   s    
zLayout.find_all_windowszIterable[UIControl]c                 c  s   |   D ]}|jV  qd S N)r   contentr#   r   r%   r%   r&   find_all_controlsT   s    zLayout.find_all_controlsFocusableElement)valuer   c                 C  s  t |trR|  D ]*}t |tr|jj|kr| |  dS qtd|dn@t |tr|  D ](}t |trd|j|krd| |  dS qdtd|dnt |t	r||  krtd|
 std|| _nt|}t |tr||  krtd|f || _ng }t|ddD ](}t |tr|j
 r|| qt| jD ]}||krR|| _ dS qR|r|d	 | _dS td
|dS )a  
        Focus the given UI element.

        `value` can be either:

        - a :class:`.UIControl`
        - a :class:`.Buffer` instance or the name of a :class:`.Buffer`
        - a :class:`.Window`
        - Any container object. In this case we will focus the :class:`.Window`
          from this container that was focused most recent, or the very first
          focusable :class:`.Window` of the container.
        Nz,Couldn't find Buffer in the current layout: .z7Invalid value. Container does not appear in the layout.z*Invalid value. UIControl is not focusable.z7Invalid value. Window does not appear in the layout: %rTskip_hiddenr   z,Invalid value. Container cannot be focused: )r-   r(   r2   r   buffernamer!   
ValueErrorr	   r   is_focusablecurrent_controlr   r   r   r*   r   r0   r   reversedr   )r#   r4   controlwindowscwr%   r%   r&   r!   X   sV    







zLayout.focusboolc                 C  s   t |tr$| jdkrdS | jj|kS t |tr8| j|kS t |trL| j|kS t|}t |trh| j	|kS t
|D ]}|| j	krp dS qpdS dS )z
        Check whether the given control has the focus.
        :param value: :class:`.UIControl` or :class:`.Window` instance.
        NFT)r-   r(   current_bufferr9   r	   r   r<   r   r   r*   r   )r#   r4   elementr%   r%   r&   	has_focus   s    








zLayout.has_focusr   c                 C  s   | j d jS )zI
        Get the :class:`.UIControl` to currently has the focus.
        )r   r0   r+   r%   r%   r&   r<      s    zLayout.current_control)r>   r   c                 C  s0   |   D ]}|j|kr|| _ dS qtddS )zC
        Set the :class:`.UIControl` to receive the focus.
        Nz(Control not found in the user interface.)r   r0   r*   r:   )r#   r>   Zwindowr%   r%   r&   r<      s
    
r   c                 C  s
   | j d S )z=Return the :class:`.Window` object that is currently focused.rF   )r   r+   r%   r%   r&   r*      s    zLayout.current_windowc                 C  s   | j | dS )z8Set the :class:`.Window` object to be currently focused.N)r   r   )r#   r4   r%   r%   r&   r*      s    c                 C  s   | j | jkS )z#True if we are searching right now.)r<   r   r+   r%   r%   r&   is_searching   s    zLayout.is_searchingzBufferControl | Nonec                 C  s$   | j }t|tr| j|S dS dS )zY
        Return the :class:`.BufferControl` in which we are searching or `None`.
        N)r<   r-   r   r   get)r#   r>   r%   r%   r&   search_target_buffer_control   s    
z#Layout.search_target_buffer_controlzIterable[Window]c                 c  s,   |   D ]}t|tr|j r|V  qdS )zl
        Return all the :class:`.Window` objects which are focusable (in the
        'modal' area).
        N)walk_through_modal_arear-   r   r0   r;   )r#   rA   r%   r%   r&   get_focusable_windows   s    zLayout.get_focusable_windowszlist[Window]c                   s   | j   fdd|  D S )zO
        Return a list of :class:`.Window` objects that are focusable.
        c                   s   g | ]}| kr|qS r%   r%   ).0rA   r"   r%   r&   
<listcomp>   s      z8Layout.get_visible_focusable_windows.<locals>.<listcomp>)r"   rK   r+   r%   rM   r&   get_visible_focusable_windows   s    z$Layout.get_visible_focusable_windowszBuffer | Nonec                 C  s   | j }t|tr|jS dS )zD
        The currently focused :class:`~.Buffer` or `None`.
        N)r<   r-   r   r8   r#   Z
ui_controlr%   r%   r&   rC     s    
zLayout.current_buffer)buffer_namer   c                 C  sB   |   D ]4}t|trt|jtr|jjj|kr|jj  S qdS )zt
        Look in the layout for a buffer with the given name.
        Return `None` when nothing was found.
        N)r   r-   r   r0   r   r8   r9   )r#   rQ   rA   r%   r%   r&   get_buffer_by_name  s
    zLayout.get_buffer_by_namec                 C  s   | j }t|tS )z
        Return `True` if the currently focused control is a
        :class:`.BufferControl`. (For instance, used to determine whether the
        default key bindings should be active or not.)
        )r<   r-   r   rP   r%   r%   r&   buffer_has_focus  s    zLayout.buffer_has_focusc                 C  s4   z| j d jW S  tk
r.   | j d j Y S X dS )zJ
        Get the :class:`.UIControl` to previously had the focus.
        rF   N)r   r0   
IndexErrorr+   r%   r%   r&   previous_control!  s    zLayout.previous_controlc                 C  s"   t | jdkr| jdd | _dS )z=
        Give the focus to the last focused control.
        r
   NrF   )lenr   r+   r%   r%   r&   
focus_last+  s    zLayout.focus_lastc                 C  s`   |   }t|dkr\z|| j}W n tk
r<   d}Y nX |d t| }| ||  dS )z:
        Focus the next visible/focusable Window.
        r   r
   NrO   rW   indexr*   r:   r!   r#   r?   rZ   r%   r%   r&   
focus_next2  s    
zLayout.focus_nextc                 C  s`   |   }t|dkr\z|| j}W n tk
r<   d}Y nX |d t| }| ||  dS )z>
        Focus the previous visible/focusable Window.
        r   r
   NrY   r[   r%   r%   r&   focus_previousB  s    
zLayout.focus_previousIterable[Container]c                 c  s   t | jE dH  dS )zX
        Walk through all the layout nodes (and their children) and yield them.
        N)r   r   r+   r%   r%   r&   r   R  s    zLayout.walkc                 c  s6   | j }| s$|| jkr$| j| }qt|E dH  dS )zn
        Walk through all the containers which are in the current 'modal' part
        of the layout.
        N)r*   Zis_modalr   r   )r#   rootr%   r%   r&   rJ   X  s    zLayout.walk_through_modal_areac                   s.   i  ddd fdd| j   | _dS )z=
        Update child->parent relationships mapping.
        r   r   )r$   r   c                   s"   |   D ]}|  |< | qd S r/   )get_children)r$   r@   parentsr   r%   r&   r   k  s    z-Layout.update_parents_relations.<locals>.walkN)r   r   r+   r%   ra   r&   update_parents_relationse  s    
zLayout.update_parents_relationsc                 C  s   | j   | j  d S r/   )r   clearr   resetr+   r%   r%   r&   re   t  s    
zLayout.resetr   zContainer | None)r   r   c                 C  s(   z| j | W S  tk
r"   Y dS X dS )zo
        Return the parent container for the given container, or ``None``, if it
        wasn't found.
        N)r   KeyErrorr1   r%   r%   r&   
get_parent}  s    zLayout.get_parent)N)__name__
__module____qualname____doc__r'   r,   r   r2   r!   rE   propertyr<   setterr*   rG   rI   rK   rO   rC   rR   rS   rV   rX   r\   r]   r   rJ   rc   re   rg   r%   r%   r%   r&   r      sJ    "O						c                   @  s   e Zd ZdS )r   N)rh   ri   rj   r%   r%   r%   r&   r     s   Fr   rB   r^   )r   r7   r   c                 c  sD   |rt | tr|  sdS | V  |  D ]}t||dE dH  q(dS )z:
    Walk through layout, starting at this container.
    Nr6   )r-   r   filterr`   r   )r   r7   r@   r%   r%   r&   r     s    N)F)rk   
__future__r   typingr   r   r   r   r   r   Zprompt_toolkit.bufferr	   Z
containersr   r   r   r   r   controlsr   r   r   __all__r(   r3   r   	Exceptionr   r   r%   r%   r%   r&   <module>   s      n