a
    If5                     @   s   d Z ddlZddlZddlZddlmZ ddlmZ dd Z	dd Z
G d	d
 d
ZG dd deZG dd deZdd ZedkrddlmZ edddd ddlmZ ee dS )zLine numbering implementation for IDLE as an extension.
Includes BaseSideBar which can be extended for other sidebar based extensions
    N)idleConf)	Delegatorc                 C   s   t t| dS )z:Utility to get the last line's number in a Tk text widget.zend-1c)intfloatindex)text r    lib/python3.9/idlelib/sidebar.pyget_end_linenumber   s    r
   c                 C   s   |   }|dkr|  }n |dkr,|  }ntd| tt| jj|d | d| dg}tt| jj|d | d| dg}||fS )z;Get the total padding of a Tk widget, including its border.packgridzUnsupported geometry manager: padxZborderpady)	Zwinfo_managerZ	pack_infoZ	grid_info
ValueErrorsummaptkZgetintZcget)ZwidgetZmanagerinfor   r   r   r   r	   get_widget_padding   s"    



r   c                   @   sh   e Z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S )BaseSideBarz@
    The base class for extensions which require a sidebar.
    c              	   C   sx   || _ |j| _|j| _t| j\}}tj| jdtjd|ddd| _| jj	tj
d | j| jd< |   |   d| _d S )N      r   )widthwrapr   r   ZborderwidthZhighlightthicknessstateZyscrollcommandF)editwin
text_frameparentr   r   r   TextNONEsidebar_textconfigDISABLEDredirect_yscroll_eventupdate_fontupdate_colorsis_shown)selfr   Z_padxr   r   r   r	   __init__/   s    zBaseSideBar.__init__c                 C   s   t | jdd}| | dS )z;Update the sidebar text font, usually after config changes.mainEditorWindowN)r   GetFontr   _update_fontr(   fontr   r   r	   r%   ?   s    zBaseSideBar.update_fontc                 C   s   || j d< d S )Nr/   )r!   r.   r   r   r	   r-   D   s    zBaseSideBar._update_fontc                 C   s*   t t  d}| j|d |d d dS )=Update the sidebar text colors, usually after config changes.Znormal
foreground
backgroundr1   r2   Nr   ZGetHighlightZCurrentTheme_update_colorsr(   Zcolorsr   r   r	   r&   G   s    
zBaseSideBar.update_colorsc                 C   s   | j j|||||d d S )N)ZfgZbgZselectforegroundZselectbackgroundZinactiveselectbackground)r!   r"   )r(   r1   r2   r   r   r	   r5   M   s
    zBaseSideBar._update_colorsc                 C   s$   | j s | jjddtjd d| _ d S )Nr   r   rowcolumnZstickyT)r'   r!   r   r   NSEWr(   r   r   r	   show_sidebarT   s    zBaseSideBar.show_sidebarc                 C   s   | j r| j  d| _ d S )NF)r'   r!   Zgrid_forgetr;   r   r   r	   hide_sidebarY   s    
zBaseSideBar.hide_sidebarc                 O   s"   | j jj|  | j|d  dS )zmRedirect vertical scrolling to the main editor text widget.

        The scroll bar is also updated.
        r   break)r   vbarsetr!   yview_moveto)r(   argskwargsr   r   r	   r$   ^   s    z"BaseSideBar.redirect_yscroll_eventc                 C   s   | j   dS )z8Redirect focus-in events to the main editor text widget.r>   )r   	focus_setr(   eventr   r   r	   redirect_focusin_eventg   s    
z"BaseSideBar.redirect_focusin_eventc                 C   s"   | j   | j j|d|jd dS )z<Redirect mouse button events to the main editor text widget.r   )xyr>   )r   rD   event_generaterI   )r(   rF   
event_namer   r   r	   redirect_mousebutton_eventl   s    
z&BaseSideBar.redirect_mousebutton_eventc                 C   s   | j jdd|j|jd dS )z7Redirect mouse wheel events to the editwin text widget.<MouseWheel>r   )rH   rI   deltar>   )r   rJ   rI   rN   rE   r   r   r	   redirect_mousewheel_eventr   s    
z%BaseSideBar.redirect_mousewheel_eventN)__name__
__module____qualname____doc__r)   r%   r-   r&   r5   r<   r=   r$   rG   rL   rO   r   r   r   r	   r   +   s   	r   c                   @   s,   e Zd ZdZdd Zd	ddZd
ddZdS )EndLineDelegatorz\Generate callbacks with the current end line number after
       insert or delete operationsc                 C   s   t |  || _dS )z
        changed_callback - Callable, will be called after insert
                           or delete operations with the current
                           end line number.
        N)r   r)   changed_callback)r(   rU   r   r   r	   r)   |   s    
zEndLineDelegator.__init__Nc                 C   s$   | j ||| | t| j  d S N)delegateinsertrU   r
   )r(   r   charsZtagsr   r   r	   rX      s    zEndLineDelegator.insertc                 C   s"   | j || | t| j  d S rV   )rW   deleterU   r
   )r(   Zindex1Zindex2r   r   r	   rZ      s    zEndLineDelegator.delete)N)N)rP   rQ   rR   rS   r)   rX   rZ   r   r   r   r	   rT   y   s   	
rT   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )LineNumbersz(Line numbers support for editor windows.c                 C   s   t | | d| _t| jd | _| jjtjd | j	ddd | jjtj
d | jjddd | jjdtjd	 |   t| j}| | t| j}|| jjj | jj| | jjj}||ur|  |j}qd| _d S )
Nr   r   r   rX   1
linenumberF)Z	takefocusZexportselection)Zjustify)r   r)   prev_endtyper!   _sidebar_width_typer"   r   NORMALrX   r#   Z
tag_configZRIGHTbind_eventsr
   r   update_sidebar_textrT   Zsetdelegater   ZundorW   ZpertopZ
resetcacher'   )r(   r   endZend_line_delegatorZ	delegatorr   r   r	   r)      s&    



zLineNumbers.__init__c                    s4  j dj j dj fdd}dD ]j}d| dd| dd	| d
fD ]}|||d qVd| dd| dfD ]}||d| dd qq0d d  fdd}j d| fdd}j d| fdd  fdd}j d|  fdd}j d| d S )Nz	<FocusIn>rM   c                    s"   t j j|d} j| | d S )N)rK   )	functoolspartialrL   r!   bind)rK   target_event_nameZhandlerr;   r   r	   bind_mouse_event   s    z1LineNumbers.bind_events.<locals>.bind_mouse_event)r            z<Button->z<ButtonRelease-z<Bz-Motion>)ri   z<Double-Button-z<Triple-Button-c                    sl   t t jd| j } jddd  jd| d|d  d  jd|d  d |d S )N@0,sel1.0re   .0r   rX   )	r   r   r!   r   rI   r   
tag_removetag_addmark_set)rF   linenor(   
start_liner   r	   b1_mousedown_handler   s
     z5LineNumbers.bind_events.<locals>.b1_mousedown_handlerz
<Button-1>c                    s   d d  d d S rV   r   )rF   )last_y
last_yviewrx   r   r	   b1_mouseup_handler   s    z3LineNumbers.bind_events.<locals>.b1_mouseup_handlerz<ButtonRelease-1>c                    s   t t jd|  }t|g\}} jddd  jd| d|d  d  jd||krn|n|d  d dS )	z6Helper function for drag and selection event handlers.ro   rp   rq   re   rr   r   rX   N)	r   r   r!   r   sortedr   rs   rt   ru   )Zy_coordrv   abrw   r   r	   %drag_update_selection_and_insert_mark   s     zFLineNumbers.bind_events.<locals>.drag_update_selection_and_insert_markc                    sJ   | j j d  kr*j ks<n jd   | j  d S Nr   )rI   r!   yviewZwinfo_heightr   rA   )rF   rB   r   rz   r{   r(   r   r	   b1_drag_handler   s
    
z0LineNumbers.bind_events.<locals>.b1_drag_handlerz<B1-Motion>c                    s:   d u rd S j  }|kr6j|d    d S r   )r!   r   r   rA   )rF   r   r   r   r	   selection_handler  s    
z2LineNumbers.bind_events.<locals>.selection_handlerz<<Selection>>)r!   rh   rG   rO   )r(   rj   ZbuttonrK   ry   r|   r   r   r   )r   rz   r{   r(   rx   r	   rb      s4    







	zLineNumbers.bind_eventsc                 C   s*   t t  d}| j|d |d d dS )r0   r]   r1   r2   r3   Nr4   r6   r   r   r	   r&     s    
zLineNumbers.update_colorsc                 C   s   || j krdS tt|tt| j  }|rVtt| jd }|| }| || jd< | jjtj	d || j krd
tdgttt| j d |d }| jd|d n| j|d  d	d | jjtjd || _ dS )
z
        Perform the following action:
        Each line sidebar_text contains the linenumber for that line
        Synchronize with editwin.text so that both sidebar_text and
        editwin.text contain the same number of linesNr   r   
 r   zend -1cr]   z.0 -1c)r^   lenstrr   r   r!   r`   r"   r   ra   join	itertoolschainr   rangerX   rZ   r#   )r(   re   Zwidth_differenceZ	cur_widthZ	new_widthZnew_textr   r   r	   rc     s"    

zLineNumbers.update_sidebar_textN)rP   rQ   rR   rS   r)   rb   r&   rc   r   r   r   r	   r[      s
   jr[   c              	   C   s   ddl m} t| }t|}|jtjtjdd |jddd |j	ddd t
|dd}tj|d	d
tj|d}|jddtjd ||}t||_t|}|  |dddd tddD  d S )Nr   )Dummy_editwinT)ZsideZfillexpandr   )Zweightr*   r+   P      )r   Zheightr   r/   r7   rq   r   c                 s   s   | ]}d | V  qdS )r~   Nr   ).0ir   r   r	   	<genexpr>M      z._linenumbers_drag_scrolling.<locals>.<genexpr>e   )Zidlelib.idle_test.test_sidebarr   r   ZToplevelZFramer   ZLEFTZBOTHZrowconfigureZcolumnconfigurer   r,   r   r    r   r:   Z	Scrollbarr?   r[   r<   rX   r   r   )r   r   Ztoplevelr   r/   r   r   Zlinenumbersr   r   r	   _linenumbers_drag_scrolling:  s    

r   __main__)r*   zidlelib.idle_test.test_sidebarr   F)	verbosityexit)run)rS   rf   r   Ztkinterr   Zidlelib.configr   Zidlelib.delegatorr   r
   r   r   rT   r[   r   rP   Zunittestr*   Zidlelib.idle_test.htestr   r   r   r   r	   <module>   s"   N -