B
    ]”t\â‹  ã            ,   @   sÌ  d Z ddlZddlZddlZddlmZ ddlZddlm	Z	 ddl
mZ ddlmZ G dd„ deƒZeƒ ZdZG d	d
„ d
eƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd „ d eƒZG d!d"„ d"eƒZG d#d$„ d$eƒZG d%d&„ d&eƒZ G d'd(„ d(eƒZ!G d)d*„ d*eƒZ"G d+d,„ d,eƒZ#G d-d.„ d.e#ƒZ$G d/d0„ d0e#ƒZ%G d1d2„ d2e#ƒZ&G d3d4„ d4eƒZ'G d5d6„ d6eƒZ(G d7d8„ d8eƒZ)G d9d:„ d:e)ƒZ*G d;d<„ d<e)ƒZ+G d=d>„ d>eƒZ,G d?d@„ d@eƒZ-dAe$dBe%dCe&dDe*dEe+dFdGdHdIdJedKedLedMedNedOedPedQe!dRe dSeee"dTdUdVdWdXdYdZd[iZ.d\dAdBdCggd]dEdDdFggd^dHdXgggZ/e.fd_d`„Z0e/fdadb„Z1dS )caR  
Abstract base classes define the primitives for Tools.
These tools are used by `matplotlib.backend_managers.ToolManager`

:class:`ToolBase`
    Simple stateless tool

:class:`ToolToggleBase`
    Tool that has two states, only one Toggle tool can be
    active at any given time for the same
    `matplotlib.backend_managers.ToolManager`
é    N)ÚWeakKeyDictionary)ÚrcParams)ÚGcfc               @   s"   e Zd ZdZedƒ\ZZZZZ	dS )ÚCursorsz%Simple namespace for cursor referenceé   N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚrangeZHANDÚPOINTERÚSELECT_REGIONÚMOVEZWAIT© r   r   ú7lib/python3.7/site-packages/matplotlib/backend_tools.pyr      s   r   Zviewposc               @   s|   e Zd ZdZdZdZdZdd„ Zedd„ ƒZ	e	j
dd„ ƒZ	edd	„ ƒZed
d„ ƒZdd„ Zddd„Zedd„ ƒZdd„ ZdS )ÚToolBaseaõ  
    Base tool class

    A base tool, only implements `trigger` method or not method at all.
    The tool is instantiated by `matplotlib.backend_managers.ToolManager`

    Attributes
    ----------
    toolmanager: `matplotlib.backend_managers.ToolManager`
        ToolManager that controls this Tool
    figure: `FigureCanvas`
        Figure instance that is affected by this Tool
    name: String
        Used as **Id** of the tool, has to be unique among tools of the same
        ToolManager
    Nc             C   s    t  d¡ || _|| _d | _d S )Nz’Treat the new Tool classes introduced in v1.5 as experimental for now, the API will likely change in version 2.1, and some tools might change name)ÚwarningsÚwarnÚ_nameÚ_toolmanagerÚ_figure)ÚselfÚtoolmanagerÚnamer   r   r   Ú__init__M   s
    zToolBase.__init__c             C   s   | j S )N)r   )r   r   r   r   ÚfigureU   s    zToolBase.figurec             C   s   |   |¡ d S )N)Ú
set_figure)r   r   r   r   r   r   Y   s    c             C   s   | j s
d S | j jS )N)r   Úcanvas)r   r   r   r   r   ]   s    zToolBase.canvasc             C   s   | j S )N)r   )r   r   r   r   r   c   s    zToolBase.toolmanagerc             C   s
   || _ dS )zm
        Assign a figure to the tool

        Parameters
        ----------
        figure: `Figure`
        N)r   )r   r   r   r   r   r   g   s    zToolBase.set_figurec             C   s   dS )aŽ  
        Called when this tool gets used

        This method is called by
        `matplotlib.backend_managers.ToolManager.trigger_tool`

        Parameters
        ----------
        event: `Event`
            The Canvas event that caused this tool to be called
        sender: object
            Object that requested the tool to be triggered
        data: object
            Extra data
        Nr   )r   ÚsenderÚeventÚdatar   r   r   Útriggerq   s    zToolBase.triggerc             C   s   | j S )zTool Id)r   )r   r   r   r   r   „   s    zToolBase.namec             C   s   dS )z›
        Destroy the tool

        This method is called when the tool is removed by
        `matplotlib.backend_managers.ToolManager.remove_tool`
        Nr   )r   r   r   r   Údestroy‰   s    zToolBase.destroy)N)r   r   r	   r
   Údefault_keymapÚdescriptionÚimager   Úpropertyr   Úsetterr   r   r   r!   r   r"   r   r   r   r   r   #   s   

r   c               @   sV   e Zd ZdZdZdZdZdd„ Zddd„Zddd	„Z	dd
d„Z
edd„ ƒZdd„ ZdS )ÚToolToggleBasea`  
    Toggleable tool

    Every time it is triggered, it switches between enable and disable

    Parameters
    ----------
    ``*args``
        Variable length argument to be used by the Tool
    ``**kwargs``
        `toggled` if present and True, sets the initial state of the Tool
        Arbitrary keyword arguments to be consumed by the Tool
    NFc             O   s&   |  d| j¡| _tj| f|ž|Ž d S )NÚtoggled)ÚpopÚdefault_toggledÚ_toggledr   r   )r   ÚargsÚkwargsr   r   r   r   ¯   s    zToolToggleBase.__init__c             C   s*   | j r|  |¡ n
|  |¡ | j  | _ dS )z4Calls `enable` or `disable` based on `toggled` valueN)r,   ÚdisableÚenable)r   r   r   r    r   r   r   r!   ³   s    
zToolToggleBase.triggerc             C   s   dS )ze
        Enable the toggle tool

        `trigger` calls this method when `toggled` is False
        Nr   )r   r   r   r   r   r0   »   s    zToolToggleBase.enablec             C   s   dS )as  
        Disable the toggle tool

        `trigger` call this method when `toggled` is True.

        This can happen in different circumstances

        * Click on the toolbar tool button
        * Call to `matplotlib.backend_managers.ToolManager.trigger_tool`
        * Another `ToolToggleBase` derived tool is triggered
          (from the same `ToolManager`)
        Nr   )r   r   r   r   r   r/   Ä   s    zToolToggleBase.disablec             C   s   | j S )zState of the toggled tool)r,   )r   r   r   r   r)   Ô   s    zToolToggleBase.toggledc             C   sP   | j }|r$| jr|  | d ¡ nd| _t | |¡ |rL|rF|  | d ¡ nd| _d S )NFT)r)   r   r!   r,   r   r   )r   r   r)   r   r   r   r   Ú   s    zToolToggleBase.set_figure)N)N)N)r   r   r	   r
   Úradio_groupÚcursorr+   r   r!   r0   r/   r&   r)   r   r   r   r   r   r(   “   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S )ÚSetCursorBasezª
    Change to the current cursor while inaxes

    This tool, keeps track of all `ToolToggleBase` derived tools, and calls
    set_cursor when a tool gets triggered
    c             O   sb   t j| f|ž|Ž d | _d | _tj| _| j| _| j 	d| j
¡ x| jj ¡ D ]}|  |¡ qLW d S )NZtool_added_event)r   r   Ú_idDragÚ_cursorÚcursorsr   Ú_default_cursorÚ_last_cursorr   Útoolmanager_connectÚ_add_tool_cbkÚtoolsÚvaluesÚ	_add_tool)r   r-   r.   Útoolr   r   r   r   ô   s    zSetCursorBase.__init__c             C   s:   | j r| j | j ¡ t | |¡ |r6| j d| j¡| _ d S )NÚmotion_notify_event)r4   r   Úmpl_disconnectr   r   Úmpl_connectÚ_set_cursor_cbk)r   r   r   r   r   r     s    zSetCursorBase.set_figurec             C   s*   |j jr|j j| _nd | _|  |j¡ d S )N)r>   r)   r2   r5   rB   Zcanvasevent)r   r   r   r   r   Ú_tool_trigger_cbk	  s    zSetCursorBase._tool_trigger_cbkc             C   s*   t |ddƒdk	r&| j d|j | j¡ dS )z)set the cursor when the tool is triggeredr2   Nztool_trigger_%s)Úgetattrr   r9   r   rC   )r   r>   r   r   r   r=     s    zSetCursorBase._add_toolc             C   s   |j | krdS |  |j ¡ dS )zProcess every newly added toolN)r>   r=   )r   r   r   r   r   r:     s    
zSetCursorBase._add_tool_cbkc             C   sj   |sd S t |ddƒr| js<| j| jkrf|  | j¡ | j| _n*| jrf| j}|rf| j|krf|  |¡ || _d S )NÚinaxesF)rD   r5   r8   r7   Ú
set_cursor)r   r   r2   r   r   r   rB     s    

zSetCursorBase._set_cursor_cbkc             C   s   t ‚dS )zW
        Set the cursor

        This method has to be implemented per backend
        N)ÚNotImplementedError)r   r2   r   r   r   rF   ,  s    zSetCursorBase.set_cursorN)r   r   r	   r
   r   r   rC   r=   r:   rB   rF   r   r   r   r   r3   í   s   r3   c               @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚToolCursorPositionzƒ
    Send message with the current pointer position

    This tool runs in the background reporting the position of the cursor
    c             O   s   d | _ tj| f|ž|Ž d S )N)r4   r   r   )r   r-   r.   r   r   r   r   ;  s    zToolCursorPosition.__init__c             C   s:   | j r| j | j ¡ t | |¡ |r6| j d| j¡| _ d S )Nr?   )r4   r   r@   r   r   rA   Úsend_message)r   r   r   r   r   r   ?  s    zToolCursorPosition.set_figurec          	      sÊ   | j j ¡ rdS d}ˆ jr¸ˆ j ¡ r¸yˆ j ˆ jˆ j¡}W n tt	fk
rR   Y nfX ‡ fdd„ˆ jj
D ƒ}|r´t |¡}|ˆ jjk	r´| ˆ ¡}|dk	r´| |¡}|dk	r´|d | }|}| j  || ¡ dS )z<Call `matplotlib.backend_managers.ToolManager.message_event`Nú c                s"   g | ]}|  ˆ ¡r| ¡ r|‘qS r   )ÚcontainsZget_visible)Ú.0Úa)r   r   r   ú
<listcomp>T  s    z3ToolCursorPosition.send_message.<locals>.<listcomp>)r   ÚmessagelockÚlockedrE   Úget_navigateZformat_coordZxdataZydataÚ
ValueErrorÚOverflowErrorZ_mouseover_setÚcbookZ_topmost_artistZpatchZget_cursor_dataZformat_cursor_dataÚmessage_event)r   r   ÚmessageÚsZartistsrM   r    Zdata_strr   )r   r   rI   G  s&    


zToolCursorPosition.send_messageN)r   r   r	   r
   r   r   rI   r   r   r   r   rH   5  s   rH   c               @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚRubberbandBasezDraw and remove rubberbandc             C   s4   | j jj |¡sdS |dk	r(| j|Ž  n|  ¡  dS )z;Call `draw_rubberband` or `remove_rubberband` based on dataN)r   r   Ú
widgetlockZ	availableÚdraw_rubberbandÚremove_rubberband)r   r   r   r    r   r   r   r!   f  s
    zRubberbandBase.triggerc             G   s   t ‚dS )zW
        Draw rubberband

        This method must get implemented per backend
        N)rG   )r   r    r   r   r   rZ   o  s    zRubberbandBase.draw_rubberbandc             C   s   dS )z[
        Remove rubberband

        This method should get implemented per backend
        Nr   )r   r   r   r   r[   w  s    z RubberbandBase.remove_rubberbandN)r   r   r	   r
   r!   rZ   r[   r   r   r   r   rX   d  s   	rX   c               @   s&   e Zd ZdZdZed Zddd„ZdS )ÚToolQuitz.Tool to call the figure manager destroy methodzQuit the figurezkeymap.quitNc             C   s   t  | j¡ d S )N)r   Zdestroy_figr   )r   r   r   r    r   r   r   r!   †  s    zToolQuit.trigger)N)r   r   r	   r
   r$   r   r#   r!   r   r   r   r   r\   €  s   r\   c               @   s&   e Zd ZdZdZed Zddd„ZdS )ÚToolQuitAllz.Tool to call the figure manager destroy methodzQuit all figureszkeymap.quit_allNc             C   s   t  ¡  d S )N)r   Zdestroy_all)r   r   r   r    r   r   r   r!     s    zToolQuitAll.trigger)N)r   r   r	   r
   r$   r   r#   r!   r   r   r   r   r]   Š  s   r]   c               @   s&   e Zd ZdZdZed Zddd„ZdS )ÚToolEnableAllNavigationz3Tool to enable all axes for toolmanager interactionzEnable all axes toolmanagerzkeymap.all_axesNc             C   sN   |j d krd S x:| j ¡ D ],}|jd k	r|jd k	r| |¡r| d¡ qW d S )NT)rE   r   Úget_axesÚxÚyÚin_axesÚset_navigate)r   r   r   r    rM   r   r   r   r!   š  s    

zToolEnableAllNavigation.trigger)N)r   r   r	   r
   r$   r   r#   r!   r   r   r   r   r^   ”  s   r^   c               @   s"   e Zd ZdZdZdZddd„ZdS )ÚToolEnableNavigationz:Tool to enable a specific axes for toolmanager interactionzEnable one axes toolmanager)	é   é   é   é   r   é   é   é   é	   Nc             C   sh   |j d krd S t|jƒd }xFt| j ¡ ƒD ]4\}}|jd k	r,|jd k	r,| |¡r,| 	||k¡ q,W d S )Nre   )
rE   ÚintÚkeyÚ	enumerater   r_   r`   ra   rb   rc   )r   r   r   r    ÚnÚirM   r   r   r   r!   ª  s    

zToolEnableNavigation.trigger)N)r   r   r	   r
   r$   r#   r!   r   r   r   r   rd   ¤  s   rd   c               @   s2   e Zd ZdZddddgZddd„Zed	d
„ ƒZdS )Ú_ToolGridBasez8Common functionality between ToolGrid and ToolMinorGrid.)FF)TF)TT)FTNc       	      C   sn   |j }|d krd S y|  |¡\}}}}W n tk
r<   Y n.X |j||dd |j||dd |jj ¡  d S )Nr`   )ZwhichZaxisra   )rE   Ú_get_next_grid_statesrR   Úgridr   r   Ú	draw_idle)	r   r   r   r    ÚaxÚx_stateZx_whichÚy_stateZy_whichr   r   r   r!   º  s    z_ToolGridBase.triggerc             C   s4   t dd„ | D ƒƒrdS tdd„ | D ƒƒs,dS dS dS )zÁ
        Check whether all grid lines are in the same visibility state.

        Returns True/False if all grid lines are on or off, None if they are
        not all in the same state.
        c             s   s   | ]}|j V  qd S )N)ÚgridOn)rL   Útickr   r   r   ú	<genexpr>Ï  s    z8_ToolGridBase._get_uniform_grid_state.<locals>.<genexpr>Tc             s   s   | ]}|j V  qd S )N)ry   )rL   rz   r   r   r   r{   Ñ  s    FN)ÚallÚany)Zticksr   r   r   Ú_get_uniform_grid_stateÇ  s
    z%_ToolGridBase._get_uniform_grid_state)N)r   r   r	   r
   Ú_cycler!   Ústaticmethodr~   r   r   r   r   rr   µ  s   
rr   c               @   s$   e Zd ZdZdZed Zdd„ ZdS )ÚToolGridz,Tool to toggle the major grids of the figurezToggle major gridszkeymap.gridc             C   s€   d t | j|jj|jjgƒkr t‚t | j|jj|jjgƒ\}}| j}|| ||f¡d t	|ƒ  \}}||rndnd||rzdndfS )Nre   ÚmajorÚboth)
Úmapr~   ÚxaxisÚ
minorTicksÚyaxisrR   Ú
majorTicksr   ÚindexÚlen)r   rv   rw   rx   Úcycler   r   r   rs   Ý  s    "zToolGrid._get_next_grid_statesN)r   r   r	   r
   r$   r   r#   rs   r   r   r   r   r   ×  s   r   c               @   s$   e Zd ZdZdZed Zdd„ ZdS )ÚToolMinorGridz6Tool to toggle the major and minor grids of the figurezToggle major and minor gridszkeymap.grid_minorc             C   sp   d t | j|jj|jjgƒkr t‚t | j|jj|jjgƒ\}}| j}|| ||f¡d t	|ƒ  \}}|d|dfS )Nre   rƒ   )
r„   r~   r…   rˆ   r‡   rR   r†   r   r‰   rŠ   )r   rv   rw   rx   r‹   r   r   r   rs   ò  s    "z#ToolMinorGrid._get_next_grid_statesN)r   r   r	   r
   r$   r   r#   rs   r   r   r   r   rŒ   ì  s   rŒ   c               @   s,   e Zd ZdZdZed Zdd„ Zdd„ ZdS )	ÚToolFullScreenzTool to toggle full screenzToggle fullscreen modezkeymap.fullscreenc             C   s   | j jj ¡  d S )N)r   r   ÚmanagerÚfull_screen_toggle)r   r   r   r   r   r0     s    zToolFullScreen.enablec             C   s   | j jj ¡  d S )N)r   r   rŽ   r   )r   r   r   r   r   r/   	  s    zToolFullScreen.disableN)	r   r   r	   r
   r$   r   r#   r0   r/   r   r   r   r   r      s
   r   c               @   s*   e Zd ZdZd	dd„Zdd„ Zdd„ ZdS )
ÚAxisScaleBasez2Base Tool to toggle between linear and logarithmicNc             C   s"   |j d krd S t | |||¡ d S )N)rE   r(   r!   )r   r   r   r    r   r   r   r!     s    
zAxisScaleBase.triggerc             C   s   |   |jd¡ | jj ¡  d S )NÚlog)Ú	set_scalerE   r   r   ru   )r   r   r   r   r   r0     s    zAxisScaleBase.enablec             C   s   |   |jd¡ | jj ¡  d S )NZlinear)r’   rE   r   r   ru   )r   r   r   r   r   r/     s    zAxisScaleBase.disable)N)r   r   r	   r
   r!   r0   r/   r   r   r   r   r     s   
r   c               @   s$   e Zd ZdZdZed Zdd„ ZdS )Ú
ToolYScalezBTool to toggle between linear and logarithmic scales on the Y axiszToggle scale Y axiszkeymap.yscalec             C   s   |  |¡ d S )N)Z
set_yscale)r   rv   Úscaler   r   r   r’   $  s    zToolYScale.set_scaleN)r   r   r	   r
   r$   r   r#   r’   r   r   r   r   r“     s   r“   c               @   s$   e Zd ZdZdZed Zdd„ ZdS )Ú
ToolXScalezBTool to toggle between linear and logarithmic scales on the X axiszToggle scale X axiszkeymap.xscalec             C   s   |  |¡ d S )N)Z
set_xscale)r   rv   r”   r   r   r   r’   .  s    zToolXScale.set_scaleN)r   r   r	   r
   r$   r   r#   r’   r   r   r   r   r•   (  s   r•   c               @   sl   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zddd„Zdd„ Z	ddd„Z
dd„ Zdd„ Zdd„ Zdd„ Zd
S )ÚToolViewsPositionsa$  
    Auxiliary Tool to handle changes in views and positions

    Runs in the background and should get used by all the tools that
    need to access the figure's history of views and positions, e.g.

    * `ToolZoom`
    * `ToolPan`
    * `ToolHome`
    * `ToolBack`
    * `ToolForward`
    c             O   s.   t ƒ | _t ƒ | _t ƒ | _tj| f|ž|Ž d S )N)r   ÚviewsÚ	positionsÚ
home_viewsr   r   )r   r-   r.   r   r   r   r   @  s    zToolViewsPositions.__init__c                sR   |ˆ j krNt ¡ ˆ j |< t ¡ ˆ j|< tƒ ˆ j|< ˆ  |¡ | ‡ fdd„¡ dS )z:Add the current figure to the stack of views and positionsc                s
   ˆ   | ¡S )N)Úupdate_home_views)Zfig)r   r   r   Ú<lambda>P  s    z/ToolViewsPositions.add_figure.<locals>.<lambda>N)r—   rT   ZStackr˜   r   r™   Úpush_currentZadd_axobserver)r   r   r   )r   r   Ú
add_figureF  s    

zToolViewsPositions.add_figurec             C   s@   || j kr<| j |  ¡  | j|  ¡  | j|  ¡  |  ¡  dS )zReset the axes stackN)r—   Úclearr˜   r™   rš   )r   r   r   r   r   rž   R  s
    
zToolViewsPositions.clearc             C   sÐ   | j | j ƒ }|dkrdS | j| j ƒ }|dkr4dS | j| j }| j ¡ }x0|D ](}||krf|| }n|| }| |¡ qPW t|ƒ |¡rÀx4|D ],}| || d d¡ | || d d¡ qW | jj	 
¡  dS )a  
        Update the view limits and position for each axes from the current
        stack position. If any axes are present in the figure that aren't in
        the current stack position, use the home view limits for those axes and
        don't update *any* positions.
        Nr   Zoriginalre   Zactive)r—   r   r˜   r™   r_   Z	_set_viewÚsetÚissubsetZ_set_positionr   ru   )r   r—   Úposr™   Zall_axesrM   Zcur_viewr   r   r   Úupdate_viewZ  s$    



zToolViewsPositions.update_viewNc             C   sf   |s
| j }tƒ }tƒ }x*| ¡ D ]}| ¡ ||< |  |¡||< q W | j|  |¡ | j|  |¡ dS )zX
        Push the current view limits and position onto their respective stacks
        N)r   r   r_   Ú	_get_viewÚ	_axes_posr—   Úpushr˜   )r   r   r—   r¡   rM   r   r   r   rœ   y  s    zToolViewsPositions.push_currentc             C   s   |  d¡ ¡ |  ¡  ¡ fS )a@  
        Return the original and modified positions for the specified axes

        Parameters
        ----------
        ax : (matplotlib.axes.AxesSubplot)
        The axes to get the positions for

        Returns
        -------
        limits : (tuple)
        A tuple of the original and modified positions
        T)Zget_positionÚfrozen)r   rv   r   r   r   r¤   ‡  s    zToolViewsPositions._axes_posc             C   s@   |s
| j }x0| ¡ D ]$}|| j| kr| ¡ | j| |< qW dS )zh
        Make sure that self.home_views has an entry for all axes present in the
        figure
        N)r   r_   r™   r£   )r   r   rM   r   r   r   rš   ™  s
    z$ToolViewsPositions.update_home_viewsc             C   sÎ   x¼| j  ¡ D ]®}t|ddƒ}t|ddƒ}t|ddƒ}g }|dk	r\| | ¡ ¡ | | ¡ ¡ |dk	r€| | ¡ ¡ | | ¡ ¡ |dk	r¤| | ¡ ¡ | | ¡ ¡ x|D ]}| ¡  qªW qW | j j ¡  dS )z(Redraw the canvases, update the locatorsr…   Nr‡   Úzaxis)	r   r_   rD   ÚappendZget_major_locatorZget_minor_locatorZrefreshr   ru   )r   rM   r…   r‡   r§   ZlocatorsZlocr   r   r   Úrefresh_locators¥  s"    
z#ToolViewsPositions.refresh_locatorsc             C   s$   | j | j  ¡  | j| j  ¡  dS )z1Recall the first view and position from the stackN)r—   r   Úhomer˜   )r   r   r   r   rª   º  s    zToolViewsPositions.homec             C   s$   | j | j  ¡  | j| j  ¡  dS )z1Back one step in the stack of views and positionsN)r—   r   Úbackr˜   )r   r   r   r   r«   ¿  s    zToolViewsPositions.backc             C   s$   | j | j  ¡  | j| j  ¡  dS )z4Forward one step in the stack of views and positionsN)r—   r   Úforwardr˜   )r   r   r   r   r¬   Ä  s    zToolViewsPositions.forward)N)N)r   r   r	   r
   r   r   rž   r¢   rœ   r¤   rš   r©   rª   r«   r¬   r   r   r   r   r–   2  s   

r–   c               @   s   e Zd ZdZdZddd„ZdS )ÚViewsPositionsBasez7Base class for `ToolHome`, `ToolBack` and `ToolForward`Nc             C   s>   | j  t¡ | j¡ t| j  t¡| jƒƒ  | j  t¡ ¡  d S )N)r   Úget_toolÚ_views_positionsr   r   rD   Ú_on_triggerr¢   )r   r   r   r    r   r   r   r!   Ï  s    
zViewsPositionsBase.trigger)N)r   r   r	   r
   r°   r!   r   r   r   r   r­   Ê  s   r­   c               @   s$   e Zd ZdZdZdZed ZdZdS )ÚToolHomezRestore the original view limzReset original viewrª   zkeymap.homeN)	r   r   r	   r
   r$   r%   r   r#   r°   r   r   r   r   r±   Ö  s
   r±   c               @   s$   e Zd ZdZdZdZed ZdZdS )ÚToolBackzMove back up the view lim stackzBack to previous viewr«   zkeymap.backN)	r   r   r	   r
   r$   r%   r   r#   r°   r   r   r   r   r²   ß  s
   r²   c               @   s$   e Zd ZdZdZdZed ZdZdS )ÚToolForwardz"Move forward in the view lim stackzForward to next viewr¬   zkeymap.forwardN)	r   r   r	   r
   r$   r%   r   r#   r°   r   r   r   r   r³   è  s
   r³   c               @   s   e Zd ZdZdZdZdS )ÚConfigureSubplotsBasez+Base tool for the configuration of subplotszConfigure subplotsÚsubplotsN)r   r   r	   r
   r$   r%   r   r   r   r   r´   ñ  s   r´   c               @   s    e Zd ZdZdZdZed ZdS )ÚSaveFigureBasezBase tool for figure savingzSave the figureZfilesavezkeymap.saveN)r   r   r	   r
   r$   r%   r   r#   r   r   r   r   r¶   ø  s   r¶   c               @   s:   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	d
„Zdd„ ZdS )ÚZoomPanBasez'Base class for `ToolZoom` and `ToolPan`c             G   sN   t j| f|žŽ  d | _d | _d | _d | _d | _d| _d| _t	 	¡ | j | _
d S )Ng       @g      à?)r(   r   Ú_button_pressedÚ_xypressÚ_idPressÚ
_idReleaseÚ	_idScrollÚ
base_scaleÚscrollthreshÚtimeÚ
lastscroll)r   r-   r   r   r   r     s    zZoomPanBase.__init__c             C   sN   | j j | ¡ | j j d| j¡| _| j j d| j¡| _| j j d| j¡| _	dS )z0Connect press/release events and lock the canvasZbutton_press_eventZbutton_release_eventZscroll_eventN)
r   r   rY   rA   Ú_pressrº   Ú_releaser»   Úscroll_zoomr¼   )r   r   r   r   r   r0     s    zZoomPanBase.enablec             C   sL   |   ¡  | jjj | ¡ | jj | j¡ | jj | j¡ | jj | j¡ dS )z6Release the canvas and disconnect press/release eventsN)	Ú_cancel_actionr   r   rY   Úreleaser@   rº   r»   r¼   )r   r   r   r   r   r/     s
    zZoomPanBase.disableNc             C   s(   | j  t¡ | j¡ t | |||¡ d S )N)r   r®   r¯   r   r   r(   r!   )r   r   r   r    r   r   r   r!     s    zZoomPanBase.triggerc             C   s¢   |j d krd S |jdkr | j}n|jdkr6d| j }nd}|j }| |j|j|g¡ t ¡ | j | jk rx| j	 
t¡ ¡  | jj ¡  t ¡ | _| j	 
t¡ ¡  d S )NZupZdownre   )rE   Úbuttonr½   Ú_set_view_from_bboxr`   ra   r¿   rÀ   r¾   r   r®   r¯   r«   r   r   ru   rœ   )r   r   Zsclrv   r   r   r   rÃ   #  s    



zZoomPanBase.scroll_zoom)N)	r   r   r	   r
   r   r0   r/   r!   rÃ   r   r   r   r   r·      s   

r·   c               @   sb   e Zd ZdZdZdZed Zej	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S )ÚToolZoomzZoom to rectangleZzoom_to_rectzkeymap.zoomÚdefaultc             G   s   t j| f|žŽ  g | _d S )N)r·   r   Ú	_ids_zoom)r   r-   r   r   r   r   I  s    zToolZoom.__init__c             C   sR   x| j D ]}| jj |¡ qW | j d| ¡ | j t¡ ¡  d | _	d | _
g | _ d S )NÚ
rubberband)rÊ   r   r   r@   r   Útrigger_toolr®   r¯   r©   r¹   r¸   )r   Úzoom_idr   r   r   rÄ   M  s    zToolZoom._cancel_actionc       	   	   C   s  | j g kr|  ¡  |jdkr$d| _n|jdkr6d| _n|  ¡  dS |j|j }}g | _x^t| j 	¡ ƒD ]L\}}|dk	rf|dk	rf| 
|¡rf| ¡ rf| ¡ rf| j ||||| ¡ f¡ qfW | jj d| j¡}| jj d| j¡}| jj d| j¡}|||f| _ |j| _dS )z5the _press mouse button in zoom to rect mode callbackre   rg   Nr?   Zkey_press_eventZkey_release_event)rÊ   rÄ   rÆ   r¸   r`   ra   r¹   ro   r   r_   rb   rQ   Zcan_zoomr¨   r£   r   rA   Ú_mouse_moveÚ_switch_on_zoom_modeÚ_switch_off_zoom_modern   Ú
_zoom_mode)	r   r   r`   ra   rq   rM   Zid1Zid2Zid3r   r   r   rÁ   W  s,    





zToolZoom._pressc             C   s   |j | _|  |¡ d S )N)rn   rÑ   rÎ   )r   r   r   r   r   rÏ   y  s    zToolZoom._switch_on_zoom_modec             C   s   d | _ |  |¡ d S )N)rÑ   rÎ   )r   r   r   r   r   rÐ   }  s    zToolZoom._switch_off_zoom_modec             C   s¢   | j rž|j|j }}| j d \}}}}}t ||g||gg|jj|jj¡\\}	}
\}}| jdkrn|jj	\}
}n| jdkr„|jj
\}	}| jjd| |	|
||fd dS )zthe drag callback in zoom moder   r`   ra   rË   )r    N)r¹   r`   ra   ÚnpZclipZbboxÚminÚmaxrÑ   Z	intervalyZ	intervalxr   rÌ   )r   r   r`   ra   ÚlastxÚlastyrM   ZindÚviewZx1Zy1Zx2Zy2r   r   r   rÎ     s    *

zToolZoom._mouse_movec             C   s>  x| j D ]}| jj |¡ qW g | _ | js6|  ¡  dS g }xà| jD ]Ö}|j|j }}|\}}}	}
}t|| ƒdk s‚t|| ƒdk rŽ|  ¡  dS d\}}|rÐx4|D ],}|	 	¡  
|	|¡r¸d}|	 ¡  
|	|¡r d}q W | |	¡ | jdkrêd}n| jdkrBd}nqB|	 ||||f|| j||¡ qBW d| _| j t¡ ¡  |  ¡  dS )	z6the release mouse button callback in zoom to rect modeNr   )FFTre   Úinrg   Úout)rÊ   r   r   r@   r¹   rÄ   r`   ra   ÚabsZget_shared_x_axesZjoinedZget_shared_y_axesr¨   r¸   rÇ   rÑ   r   r®   r¯   rœ   )r   r   rÍ   Zlast_aZcur_xypressr`   ra   rÕ   rÖ   rM   Ú_indr×   ZtwinxZtwinyZlaÚ	directionr   r   r   rÂ     s>     



zToolZoom._releaseN)r   r   r	   r
   r$   r%   r   r#   r6   r   r2   r1   r   rÄ   rÁ   rÏ   rÐ   rÎ   rÂ   r   r   r   r   rÈ   @  s   
"rÈ   c               @   sR   e Zd ZdZed ZdZdZej	Z
dZdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ ZdS )ÚToolPanz)Pan axes with left mouse, zoom with rightz
keymap.panZmoverÉ   c             G   s   t j| f|žŽ  d | _d S )N)r·   r   r4   )r   r-   r   r   r   r   Ç  s    zToolPan.__init__c             C   s>   d | _ g | _| jj | j¡ | jj | ¡ | j 	t
¡ ¡  d S )N)r¸   r¹   r   r   r@   r4   r   rO   rÅ   r®   r¯   r©   )r   r   r   r   rÄ   Ë  s
    zToolPan._cancel_actionc             C   sÎ   |j dkrd| _n|j dkr$d| _n|  ¡  d S |j|j }}g | _x„t| j ¡ ƒD ]r\}}|d k	rT|d k	rT| 	|¡rT| 
¡ rT| ¡ rT| |||j ¡ | j ||f¡ | j | ¡ | jj d| j¡| _qTW d S )Nre   rg   r?   )rÆ   r¸   rÄ   r`   ra   r¹   ro   r   r_   rb   rQ   Zcan_panZ	start_panr¨   r   rO   r   rA   rÎ   r4   )r   r   r`   ra   rq   rM   r   r   r   rÁ   Ò  s     

zToolPan._pressc             C   s~   | j d kr|  ¡  d S | jj | j¡ | jj | ¡ x| j	D ]\}}| 
¡  q<W | j	sb|  ¡  d S | j t¡ ¡  |  ¡  d S )N)r¸   rÄ   r   r   r@   r4   r   rO   rÅ   r¹   Zend_panr®   r¯   rœ   )r   r   rM   rÛ   r   r   r   rÂ   ç  s    
zToolPan._releasec             C   s<   x*| j D ] \}}| | j|j|j|j¡ qW | jj ¡  d S )N)	r¹   Zdrag_panr¸   rn   r`   ra   r   r   ru   )r   r   rM   rÛ   r   r   r   rÎ   ø  s    zToolPan._mouse_moveN)r   r   r	   r
   r   r#   r$   r%   r6   r   r2   r1   r   rÄ   rÁ   rÂ   rÎ   r   r   r   r   rÝ   ¾  s   rÝ   c               @   sH   e Zd ZdZed ZdZedd„ ƒZdd„ Z	dd	„ Z
d
d„ Zdd„ ZdS )ÚToolHelpBasez*Print tool list, shortcuts and descriptionzkeymap.helpzhelp.pngc             C   s"   t | ƒdkr| S t dd| ¡ ¡ S )z¦
        Converts a shortcut string from the notation used in rc config to the
        standard notation for displaying shortcuts, e.g. 'ctrl+a' -> 'Ctrl+A'.
        re   z\+[A-Z]z+Shift\g<0>)rŠ   ÚreÚsubÚtitle)Zkey_sequencer   r   r   Úformat_shortcut  s    zToolHelpBase.format_shortcutc                s$   ˆ j  |¡}d ‡ fdd„|D ƒ¡S )Nz, c             3   s   | ]}ˆ   |¡V  qd S )N)râ   )rL   Zkeymap)r   r   r   r{     s    z3ToolHelpBase._format_tool_keymap.<locals>.<genexpr>)r   Zget_tool_keymapÚjoin)r   r   Zkeymapsr   )r   r   Ú_format_tool_keymap  s    z ToolHelpBase._format_tool_keymapc             C   sF   g }x<t | jj ¡ ƒD ](\}}|js&q| ||  |¡|jf¡ qW |S )N)Úsortedr   r;   Úitemsr$   r¨   rä   )r   Úentriesr   r>   r   r   r   Ú_get_help_entries  s    zToolHelpBase._get_help_entriesc             C   s    |   ¡ }dd„ |D ƒ}d |¡S )Nc             S   s   g | ]}d j |Ž ‘qS )z
{}: {}
	{})Úformat)rL   Úentryr   r   r   rN     s    z/ToolHelpBase._get_help_text.<locals>.<listcomp>Ú
)rè   rã   )r   rç   r   r   r   Ú_get_help_text  s    zToolHelpBase._get_help_textc                sP   d‰ ˆ   ddd¡g}|‡ fdd„|  ¡ D ƒ7 }d|d  d	 |d
d … ¡ d S )Nz*<tr><td>{}</td><td>{}</td><td>{}</td></tr>z<b>Action</b>z<b>Shortcuts</b>z<b>Description</b>c                s   g | ]}ˆ j |Ž ‘qS r   )ré   )rL   Úrow)Úfmtr   r   rN   $  s    z/ToolHelpBase._get_help_html.<locals>.<listcomp>z2<style>td {padding: 0px 4px}</style><table><thead>r   z</thead><tbody>re   z</tbody></table>)ré   rè   rã   )r   Zrowsr   )rî   r   Ú_get_help_html   s
    zToolHelpBase._get_help_htmlN)r   r   r	   r$   r   r#   r%   r€   râ   rä   rè   rì   rï   r   r   r   r   rÞ      s   		rÞ   c               @   s$   e Zd ZdZdZed Zdd„ ZdS )ÚToolCopyToClipboardBasez(Tool to copy the figure to the clipboardz#Copy the canvas figure to clipboardzkeymap.copyc             O   s   d}| j  || ¡ d S )NzCopy tool is not available)r   rU   )r   r-   r.   rV   r   r   r   r!   0  s    zToolCopyToClipboardBase.triggerN)r   r   r	   r
   r$   r   r#   r!   r   r   r   r   rð   *  s   rð   rª   r«   r¬   ZzoomZpanrµ   ZToolConfigureSubplotsZsaveZToolSaveFigurert   Z
grid_minorZ
fullscreenÚquitZquit_allZallnavZnavZxscaleZyscaleÚpositionr2   ZToolSetCursorrË   ZToolRubberbandÚhelpZToolHelpÚcopyZToolCopyToClipboardZ
navigationZzoompanÚioc             C   s&   x |  ¡ D ]\}}|  ||¡ q
W dS )a4  
    Add multiple tools to `ToolManager`

    Parameters
    ----------
    toolmanager: ToolManager
        `backend_managers.ToolManager` object that will get the tools added
    tools : {str: class_like}, optional
        The tools to add in a {name: tool} dict, see `add_tool` for more
        info.
    N)ræ   Úadd_tool)r   r;   r   r>   r   r   r   Úadd_tools_to_managerQ  s    r÷   c             C   s:   x4|D ],\}}x"t |ƒD ]\}}|  |||¡ qW qW dS )a  
    Add multiple tools to the container.

    Parameters
    ----------
    container: Container
        `backend_bases.ToolContainerBase` object that will get the tools added
    tools : list, optional
        List in the form
        [[group1, [tool1, tool2 ...]], [group2, [...]]]
        Where the tools given by tool1, and tool2 will display in group1.
        See `add_tool` for details.
    N)ro   rö   )Z	containerr;   ÚgroupZ
grouptoolsrò   r>   r   r   r   Úadd_tools_to_containerb  s    rù   )2r
   rß   r¿   r   Úweakrefr   ZnumpyrÒ   Z
matplotlibr   Zmatplotlib._pylab_helpersr   Zmatplotlib.cbookrT   Úobjectr   r6   r¯   r   r(   r3   rH   rX   r\   r]   r^   rd   rr   r   rŒ   r   r   r“   r•   r–   r­   r±   r²   r³   r´   r¶   r·   rÈ   rÝ   rÞ   rð   Zdefault_toolsZdefault_toolbar_toolsr÷   rù   r   r   r   r   Ú<module>   s€   pZH/

"

 			@~B*