U
    Z+diK                     @  s   d dl mZ d dlmZmZmZ d dlmZ d dlm	Z	m
Z
 d dlmZ d dlmZ ddlmZmZ dd	lmZmZmZmZ dd
lmZmZ ddlmZmZmZ dgZdZG dd deZ dS )    )annotations)DictListOptional)Point)FilterOrBool	to_filter)KeyBindingsBase)
MouseEvent   )	ContainerScrollOffsets)AnyDimension	Dimensionsum_layout_dimensionsto_dimension)MouseHandlerMouseHandlers)CharScreenWritePositionScrollablePanei'  c                   @  sH  e Zd ZdZdddeddddddf
ddddd	d
d
dddd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dZ	dddddd dd!d"d#Z
d$dd$d%d&d'Zdddd	dd(d)d*Zdddd	dd+d,d-Zddddd.d/d0Zddd1d2Zd3dd4d5Zd6dd7d8Zd	d	dd9dd:d;d<Zdd	ddd=d>d?ZdS )@r   aK  
    Container widget that exposes a larger virtual screen to its content and
    displays it in a vertical scrollbale region.

    Typically this is wrapped in a large `HSplit` container. Make sure in that
    case to not specify a `height` dimension of the `HSplit`, so that it will
    scale according to the content.

    .. note::

        If you want to display a completion menu for widgets in this
        `ScrollablePane`, then it's still a good practice to use a
        `FloatContainer` with a `CompletionsMenu` in a `Float` at the top-level
        of the layout hierarchy, rather then nesting a `FloatContainer` in this
        `ScrollablePane`. (Otherwise, it's possible that the completion menu
        is clipped.)

    :param content: The content container.
    :param scrolloffset: Try to keep the cursor within this distance from the
        top/bottom (left/right offset is not used).
    :param keep_cursor_visible: When `True`, automatically scroll the pane so
        that the cursor (of the focused window) is always visible.
    :param keep_focused_window_visible: When `True`, automatically scroll th e
        pane so that the focused window is visible, or as much visible as
        possible if it doen't completely fit the screen.
    :param max_available_height: Always constraint the height to this amount
        for performance reasons.
    :param width: When given, use this width instead of looking at the children.
    :param height: When given, use this height instead of looking at the children.
    :param show_scrollbar: When `True` display a scrollbar on the right.
    NT^vr   zScrollOffsets | Noner   intr   strNone)contentscroll_offsetskeep_cursor_visiblekeep_focused_window_visiblemax_available_heightwidthheightshow_scrollbardisplay_arrowsup_arrow_symboldown_arrow_symbolreturnc                 C  sh   || _ |ptddd| _t|| _t|| _|| _|| _|| _t|| _	t|	| _
|
| _|| _d| _d S )Nr   )topbottomr   )r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   vertical_scroll)selfr   r   r   r    r!   r"   r#   r$   r%   r&   r'    r-   I/tmp/pip-unpacked-wheel-blk8czbf/prompt_toolkit/layout/scrollable_pane.py__init__6   s    



zScrollablePane.__init__)r(   c                 C  s   d| j dS )NzScrollablePane()r   r,   r-   r-   r.   __repr__R   s    zScrollablePane.__repr__c                 C  s   | j   d S N)r   resetr2   r-   r-   r.   r5   U   s    zScrollablePane.resetr   )max_available_widthr(   c                 C  s>   | j d k	rt| j S | j|}|  r:ttd|gS |S )Nr   )r"   r   r   preferred_widthr$   r   r   exact)r,   r6   Zcontent_widthr-   r-   r.   r7   X   s    

zScrollablePane.preferred_width)r"   r!   r(   c                 C  sB   | j d k	rt| j S |  r$|d8 }| j|| j}td|jdS )Nr   r   )min	preferred)r#   r   r$   r   preferred_heightr!   r   r:   )r,   r"   r!   	dimensionr-   r-   r.   r;   f   s    

zScrollablePane.preferred_heightr   r   r   boolz
int | None)screenmouse_handlerswrite_positionparent_styleerase_bgz_indexr(   c                 C  s4  |   }|r|jd }n|j}| j|| jj}	t|	|j}	t|	| j}	t	t
d|dd}
|j|
_tdd||	d}t }| j|
||||| |
  ddlm} | jj}z|
j| }W n tk
r   Y nX | |j|	||
j| | ||
|| | |||| |j}|j}t|j|| |_t|j||j |_| ||
| |
jrXd|_|
j D ]v\}}d|j  kr|jk rbn nL| j |j!  kr|j| j  k rbn n$t"|j| |j!| | j  d	|j|< qb|
j# D ]6\}}| $t"|j| |j!| | j  d	||j#|< q|r0| %||	| d
S )z
        Render scrollable pane content.

        This works by rendering on an off-screen canvas, and copying over the
        visible region.
        r    )charstyle)Zdefault_charr   )xposyposr"   r#   )get_appTxyN)&r$   r"   r   r;   r!   r:   maxr#   r9   r   r   Zshow_cursorr   r   write_to_screenZdraw_all_floatsZprompt_toolkit.applicationrI   ZlayoutZcurrent_window"visible_windows_to_write_positionsKeyError_make_window_visibleZcursor_positionsget_copy_over_screen_copy_over_mouse_handlersrH   rG   _copy_over_write_positionsitemsrK   r+   rL   r   Zmenu_positions_clip_point_to_visible_area_draw_scrollbar)r,   r>   r?   r@   rA   rB   rC   r$   virtual_widthvirtual_heighttemp_screenZtemp_write_positiontemp_mouse_handlersrI   Zfocused_windowvisible_win_write_posrH   rG   Zwindowpointr-   r-   r.   rN   u   s        

    


 zScrollablePane.write_to_screenr   )r^   r@   r(   c                 C  s   |j |jk r|j|jd}|j|jk r4|j|jd}|j |j|j kr^|j|j|j d d}|j|j|j kr|j|j|j d d}|S )zV
        Ensure that the cursor and menu positions always are always reported
        )rK   )rL   r   )rK   rG   _replacerL   rH   r"   r#   )r,   r^   r@   r-   r-   r.   rW      s    z*ScrollablePane._clip_point_to_visible_area)r>   r[   r@   rY   r(   c                 C  s   |j }|j}t|jD ]v}|j|| j  }|j||  }	|j|| j  }
|j||  }t|D ],}|| |	|| < ||
kr^|
| ||| < q^qdS )zU
        Copy over visible screen content and "zero width escape sequences".
        N)rH   rG   ranger#   data_bufferr+   zero_width_escapes)r,   r>   r[   r@   rY   rH   rG   rL   Ztemp_rowrowZtemp_zero_width_escapesrb   rK   r-   r-   r.   rS      s    
z ScrollablePane._copy_over_screen)r?   r\   r@   rY   r(   c                   s   |j |ji  ddd fdd}|j}|j}t|jD ]P}||kr@||j  }	||  }
t|D ] }||	krn||	| |
| < qnq@dS )z
        Copy over mouse handlers from virtual screen to real screen.

        Note: we take `virtual_width` because we don't want to copy over mouse
              handlers that we possibly have behind the scrollbar.
        r   )handlerr(   c                   s2    kr*ddd fdd}| <   S )z:Wrap mouse handler. Translate coordinates in `MouseEvent`.r
   r   )eventr(   c                   s@   t t| jj | jjj  d| j| j| jd} | d S )NrJ   )position
event_typebutton	modifiers)	r
   r   rf   rK   rL   r+   rg   rh   ri   )re   Z	new_event)rd   r,   rG   rH   r-   r.   new_handler0  s    
	zYScrollablePane._copy_over_mouse_handlers.<locals>.wrap_mouse_handler.<locals>.new_handlerr-   )rd   rj   Zmouse_handler_wrappersr,   rG   rH   )rd   r.   wrap_mouse_handler,  s    zDScrollablePane._copy_over_mouse_handlers.<locals>.wrap_mouse_handlerN)rH   rG   r?   r`   r#   r+   )r,   r?   r\   r@   rY   rl   Zmouse_handlers_dictZtemp_mouse_handlers_dictrL   Ztemp_mouse_rowZ	mouse_rowrK   r-   rk   r.   rT     s    z(ScrollablePane._copy_over_mouse_handlers)r>   r[   r@   r(   c                 C  sP   |j }|j}|j D ]4\}}t|j| |j | | j |j|jd|j|< qdS )z3
        Copy over window write positions.
        )rG   rH   r#   r"   N)rH   rG   rO   rV   r   r+   r#   r"   )r,   r>   r[   r@   rH   rG   winZ	write_posr-   r-   r.   rU   K  s    z)ScrollablePane._copy_over_write_positionsc                 C  s
   | j  S r4   )r   is_modalr2   r-   r-   r.   rn   ^  s    zScrollablePane.is_modalzKeyBindingsBase | Nonec                 C  s
   | j  S r4   )r   get_key_bindingsr2   r-   r-   r.   ro   a  s    zScrollablePane.get_key_bindingszlist[Container]c                 C  s   | j gS r4   r1   r2   r-   r-   r.   get_childrend  s    zScrollablePane.get_childrenzPoint | None)visible_heightrZ   r]   cursor_positionr(   c                 C  s   d}|| }|   r\|dk	r\| j}|j| d |j }|j|j }	t||}tdt||	}|  r|j|kr|j	|j | }
|j	}n|j	}
|j	|j | }t||
}t||}||kr|}| j
|kr|| _
| j
|k r|| _
dS )a  
        Scroll the scrollable pane, so that this window becomes visible.

        :param visible_height: Height of this `ScrollablePane` that is rendered.
        :param virtual_height: Height of the virtual, temp screen.
        :param visible_win_write_pos: `WritePosition` of the nested window on the
            temp screen.
        :param cursor_position: The location of the cursor position of this
            window on the temp screen.
        r   Nr   )r   r   rL   r*   r)   rM   r9   r    r#   rH   r+   )r,   rq   rZ   r]   rr   Z
min_scrollZ
max_scrolloffsetsZcpos_min_scrollZcpos_max_scrollZwindow_min_scrollZwindow_max_scrollr-   r-   r.   rQ   g  sD    





z#ScrollablePane._make_window_visible)r@   content_heightr>   r(   c                   s^  |j }|  }|r|d8 }zD|j t| }| jt| }tt|td||  t|| W n tk
rt   Y dS X ddd fdd}|j|j	 d }	|j
}
|j}|rt| jd	||
 |	< |
d7 }
d
}d}d}d}t|D ]^}d}||r||d s|}n|}n||d r |}n|}td|||
 |	< |
d7 }
q|rZt| jd	||
 |	< dS )z
        Draw the scrollbar on the screen.

        Note: There is some code duplication with the `ScrollbarMargin`
              implementation.
           r   Nr   r=   )rc   r(   c                   s   |   ko  kS   S )z/True if we should display a button on this row.r-   )rc   Zscrollbar_heightZscrollbar_topr-   r.   is_scroll_button  s    z8ScrollablePane._draw_scrollbar.<locals>.is_scroll_buttonzclass:scrollbar.arrowzclass:scrollbar.backgroundz*class:scrollbar.background,scrollbar.startzclass:scrollbar.buttonz$class:scrollbar.button,scrollbar.end rD   )r#   r%   floatr+   r   r9   rM   ZeroDivisionErrorrG   r"   rH   ra   r   r&   r`   r'   )r,   r@   rt   r>   Zwindow_heightr%   Zfraction_visibleZfraction_aboverw   rG   rH   ra   Zscrollbar_backgroundZscrollbar_background_startZscrollbar_buttonZscrollbar_button_endirF   r-   rv   r.   rX     sV    
 

 zScrollablePane._draw_scrollbar)__name__
__module____qualname____doc__MAX_AVAILABLE_HEIGHTr/   r3   r5   r7   r;   rN   rW   rS   rT   rU   rn   ro   rp   rQ   rX   r-   r-   r-   r.   r      s4   #&w3BN)!
__future__r   typingr   r   r   Zprompt_toolkit.data_structuresr   Zprompt_toolkit.filtersr   r   Zprompt_toolkit.key_bindingr	   Zprompt_toolkit.mouse_eventsr
   Z
containersr   r   r<   r   r   r   r   r?   r   r   r>   r   r   r   __all__r   r   r-   r-   r-   r.   <module>   s   