
    e`                         d gZ ddlZddlZddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZmZmZ  G d de      Z G d d e      Zy)GraphicsItem    N)OrderedDict)reduce)hypot)Optional)Element   )	functions)GraphicsScene)Point)QtCore	QtWidgetsisQObjectAlivec                   8     e Zd ZdZd fd	Z fdZ fdZ xZS )LRUz?Limit size, evicting the least recently looked-up key when fullc                 2    || _         t        |   |i | y N)maxsizesuper__init__)selfr   argskwds	__class__s       F/usr/lib/python3/dist-packages/pyqtgraph/graphicsItems/GraphicsItem.pyr   zLRU.__init__   s    $'$'    c                 H    t         |   |      }| j                  |       |S r   )r   __getitem__move_to_end)r   keyvaluer   s      r   r   zLRU.__getitem__   s%    #C(r   c                     || v r| j                  |       t        | 	  ||       t        |       | j                  kD  rt        t        |             }| |= y y r   )r   r   __setitem__lenr   nextiter)r   r    r!   oldestr   s       r   r#   zLRU.__setitem__   sQ    $;S!C't9t||#$t*%FV $r   )   )__name__
__module____qualname____doc__r   r   r#   __classcell__)r   s   @r   r   r      s    E(
 r   r   c                   T   e Zd ZdZ ed      Zd Zd Zd Zd Z	d Z
d0d	Zd
 Zd Zd Zd0dZd1dZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!d0d Z"d! Z#d" Z$d# Z%d$ Z&d0d%Z'd& Z(d' Z)d( Z*d) Z+d0d*Z,d0d+Z-d, Z.d-e/e0e1f   d.e2e3e1e4e1   f      fd/Z5y)2r   aW  
    **Bases:** :class:`object`

    Abstract class providing useful methods to GraphicsObject and GraphicsWidget.
    (This is required because we cannot have multiple inheritance with QObject subclasses.)

    A note about Qt's GraphicsView framework:

    The GraphicsView system places a lot of emphasis on the notion that the graphics within the scene should be device independent--you should be able to take the same graphics and display them on screens of different resolutions, printers, export to SVG, etc. This is nice in principle, but causes me a lot of headache in practice. It means that I have to circumvent all the device-independent expectations any time I want to operate in pixel coordinates rather than arbitrary scene coordinates. A lot of the code in GraphicsItem is devoted to this task--keeping track of view widgets and device transforms, computing the size and shape of a pixel in local item coordinates, etc. Note that in item coordinates, a pixel does not have to be square or even rectangular, so just asking how to increase a bounding rect by 2px can be a rather complex task.
    d   c                 J   t        | d      sH| j                  j                  D ]/  }t        |t        j
                        s|| j                  _         n t        | d      st        dt        |       z        d d g| _	        d | _
        d | _        d | _        d| _        d | _        y )N_qtBaseClassz6Could not determine Qt base class for GraphicsItem: %sF)hasattrr   	__bases__
issubclassr   QGraphicsItemr1   	Exceptionstr_pixelVectorCache_viewWidget_viewBox_connectedView_exportOpts_cachedView)r   bs     r   r   zGraphicsItem.__init__5   s    t^,^^-- a!8!8923DNN/ t^,TWZ[_W``aa"&" r   c                 0   | j                   k| j                         }|y|j                         }t        |      dk  ryt	        j
                  | j                         j                         d         | _         | j                         }|t        |      sy|S )a  
        Return the view widget for this item. 
        
        If the scene has multiple views, only the first view is returned.
        The return value is cached; clear the cached value with forgetViewWidget().
        If the view has been deleted by Qt, return None.
        N   r   )r9   sceneviewsr$   weakrefrefr   )r   rA   rB   vs       r   getViewWidgetzGraphicsItem.getViewWidgetF   s     #JJLE}KKME5zA~&{{4::<+=+=+?+BCD=!2r   c                     d | _         y r   )r9   r   s    r   forgetViewWidgetzGraphicsItem.forgetViewWidget]   s
    r   c                    | j                   | }	 	 |j                         }|>| j                         }|yt	        j
                  |      | _         	 | j                         S t        |d      r<|j                  d      r+t	        j
                  |      | _         	 | j                         S | j                         S # t        $ r Y yw xY w)ac  
        Return the first ViewBox or GraphicsView which bounds this item's visible space.
        If this item is not contained within a ViewBox, then the GraphicsView is returned.
        If the item is contained inside nested ViewBoxes, then the inner-most ViewBox is returned.
        The result is cached; clear the cache with forgetViewBox()
        N
implementsViewBox)r:   
parentItemRuntimeErrorrF   rC   rD   r2   rK   )r   pvbs      r   
getViewBoxzGraphicsItem.getViewBox`   s     == A A 9++-Bz#(/B }} 1l+Y0G$+KKNDM}}  }} $   s   B: :	CCc                     d | _         y r   )r:   rH   s    r   forgetViewBoxzGraphicsItem.forgetViewBoxz   s	    r   Nc                     |#| j                         }|y|j                         }| j                  j                  | |      }|j	                         dk(  ry|S )z
        Return the transform that converts local item coordinates to device coordinates (usually pixels).
        Extends deviceTransform to automatically determine the viewportTransform.
        Nr   )rF   viewportTransformr1   deviceTransformdeterminant)r   rU   viewdts       r   rV   zGraphicsItem.deviceTransform}   sa    
 $%%'D| $ 6 6 8..t5FG
 >>q Ir   c                     | j                         }|yt        |d      r3|j                  d      r"| j                  |j	                               d   S | j                         S )zReturn the transform that maps from local coordinates to the item's ViewBox coordinates
        If there is no ViewBox, return the scene transform.
        Returns None if the item does not have a view.NrK   rL   r   )rQ   r2   rK   itemTransforminnerSceneItemsceneTransformr   rX   s     r   viewTransformzGraphicsItem.viewTransform   s[      <4&4??9+E%%d&9&9&;<Q??&&((r   c                     | }g }	 |j                         }|	 |S |j                         | j                  j                  z  r|j	                  |       N)zGReturn a list of parents to this item that have child clipping enabled.)rM   flagsGraphicsItemFlagItemClipsChildrenToShapeappend)r   rO   parentss      r   getBoundingParentszGraphicsItem.getBoundingParents   sV    Ay  wwy400IIIq! r   c                     | j                   | j                   S | j                         }|y| j                  |j                               }|y|j	                         }|| _         |S )zwReturn the visible bounds of this item's ViewBox or GraphicsWidget,
        in the local coordinate system of the item.N)r=   rQ   mapRectFromViewviewRect
normalized)r   rX   boundss      r   ri   zGraphicsItem.viewRect   sm     '###  <%%dmmo6>""$! r   c                 ,   | j                         }|y|j                  |j                         |j                         d|j	                         |j                         dddd	       |t        j                  dd      }n|j                         dk(  rt        d      |j                         |j	                         |j                         |j                         |j                         |j                         f}|| j                  d   k(  r&t        t        t        | j                  d               S | j                   j#                  |d      }|"||g| _        t        t        t        |            S |}t        j$                  t        j                  dd      |      }|j                  |      }|j'                         dk(  ry	 |j)                         }|j+                         }	t-        j.                  |      }
t        |
j                  |      j1                               t        |
j                  |	      j1                               f}|| j                  d<   || j                  d<   || j                   |<   | j                  d   S #  t        d|z        xY w)as  Return vectors in local coordinates representing the width and height of a view pixel.
        If direction is specified, then return vectors parallel and orthogonal to it.
        
        Return (None, None) if pixel size is not yet defined (usually because the item has not yet been displayed)
        or if pixel size is below floating-point precision limit.
        NNNr   r@   z0Cannot compute pixel length for 0-length vector.zInvalid direction %s)rV   	setMatrixm11m12m21m22r   QPointFmanhattanLengthr6   xyr8   tuplemapr   _pixelVectorGlobalCachegetQLineFlength
unitVectornormalVectorfninvertQTransformp2)r   	directionrY   r    pv
directionrdirLineviewDirnormView	normOrthodtis              r   pixelVectorszGraphicsItem.pixelVectors   s0    !!#: 	RVVXrvvxBFFHbffh1aKq!,I&&(A-NOOvvx2668RVVXy{{}ikkmT $((++UD$:$:1$=>?? ))--c48>&)2YD"U2''8 

 --q 3Z@&&/>>q 	@))+H --/I !!"%3778$'')*E#'')2D2G2G2I,JJ$&q!$'q!,.$$S)%%a((	@2J>??s    J Jc                 x    | j                  |      \  }}||y|r|j                         S |j                         S )a0  Return the length of one pixel in the direction indicated (in local coordinates)
        If ortho=True, then return the length of one pixel orthogonal to the direction indicated.
        
        Return None if pixel size is not yet defined (usually because the item has not yet been displayed).
        N)r   r|   )r   r   orthonormVorthoVs        r   pixelLengthzGraphicsItem.pixelLength   s?     )))4v=FN==?"||~r   c                     | j                         }|dk(  ryt        |d   j                         |d   j                               t        |d   j                         |d   j                               fS )Nrm   r   r@   )r   r   ru   rv   )r   rE   s     r   	pixelSizezGraphicsItem.pixelSize.  s\    adffh!)511Q4668+DEEr   c                     | j                         }|yt        j                  |      }|j                  t	        j
                  dddd            j                         S Nr   r@   rV   r   r   rx   r   r{   r|   r   vts     r   
pixelWidthzGraphicsItem.pixelWidth5  O    !!#:  $vvfmmAq!Q/07799r   c                     | j                         }|yt        j                  |      }|j                  t	        j
                  dddd            j                         S r   r   r   s     r   pixelHeightzGraphicsItem.pixelHeight=  r   r   c                 J    | j                         }|y|j                  |      S )z
        Return *obj* mapped from local coordinates to device coordinates (pixels).
        If there is no device mapping available, return None.
        N)rV   rx   r   objr   s      r   mapToDevicezGraphicsItem.mapToDeviceG  s(    
 !!#:vvc{r   c                     | j                         }|yt        |t        j                        rt        j                  |      }t        j                  |      }|j                  |      S )z
        Return *obj* mapped from device coordinates (pixels) to local coordinates.
        If there is no device mapping available, return None.
        N)rV   
isinstancer   QPointrs   r   r   rx   r   s      r   mapFromDevicezGraphicsItem.mapFromDeviceQ  sT    
 !!#:c6==)..%C  $vvc{r   c                 J    | j                         }|y|j                  |      S )z
        Return *rect* mapped from local coordinates to device coordinates (pixels).
        If there is no device mapping available, return None.
        N)rV   mapRectr   rectr   s      r   mapRectToDevicezGraphicsItem.mapRectToDevice^  s)    
 !!#:zz$r   c                 t    | j                         }|yt        j                  |      }|j                  |      S )z
        Return *rect* mapped from device coordinates (pixels) to local coordinates.
        If there is no device mapping available, return None.
        N)rV   r   r   r   r   s      r   mapRectFromDevicezGraphicsItem.mapRectFromDeviceh  s9    
 !!#:  $zz$r   c                 J    | j                         }|y |j                  |      S r   )r_   rx   r   s      r   	mapToViewzGraphicsItem.mapToViews  s&    !:vvc{r   c                 J    | j                         }|y |j                  |      S r   )r_   r   r   s      r   mapRectToViewzGraphicsItem.mapRectToViewy  s&    !:zz#r   c                 t    | j                         }|y t        j                  |      }|j                  |      S r   )r_   r   r   rx   r   s      r   mapFromViewzGraphicsItem.mapFromView  s6    !:  $vvc{r   c                 t    | j                         }|y t        j                  |      }|j                  |      S r   )r_   r   r   r   r   s      r   rh   zGraphicsItem.mapRectFromView  s6    !:  $zz#r   c                 J    t        | j                  j                  |             S r   )r   r1   posrH   s    r   r   zGraphicsItem.pos  s    T&&**4011r   c                 ^    | j                  | j                  | j                                     S r   )r   mapFromParentr   rH   s    r   viewPoszGraphicsItem.viewPos  s"    ~~d00<==r   c                 8    | j                   j                  |       S r   )r1   rM   rH   s    r   rM   zGraphicsItem.parentItem        ++D11r   c                     |5|j                         }|#| j                         |ur|j                  |        | j                  j                  | |      S r   )rA   addItemr1   setParentItem)r   parentpscenes      r   r   zGraphicsItem.setParentItem  sK    \\^F!djjl&&@t$  ..tV<<r   c                 8    | j                   j                  |       S r   )r1   
childItemsrH   s    r   r   zGraphicsItem.childItems  r   r   c                 x    | j                         | j                         S | j                  j                  |       S r   )rA   	transformr1   r]   rH   s    r   r]   zGraphicsItem.sceneTransform  s4     ::<>>##$$33D99r   c           
      L   || j                         }| j                  |      d   }|j                  t        j                  dddd            }|j                  t        j                  |j                         |j                         t        j                  dd      z               S )zReturn the rotation produced by this item's transform (this assumes there is no shear in the transform)
        If relativeItem is given, then the angle is determined relative to that item.
        r   r@   )rM   r[   rx   r   r{   angleTop1rs   )r   relativeItemtrvecs       r   transformAnglezGraphicsItem.transformAngle  s~     ??,L-a0ffV]]1Qq+,{{6==3668FNN1Q<O3OPQQr   c                 $    | j                          y)zCalled when the item's parent has changed. 
        This method handles connecting / disconnecting from ViewBox signals
        to make sure viewRangeChanged works properly. It should generally be 
        extended, not overridden.N)_updateViewrH   s    r   changeParentzGraphicsItem.changeParent  s    
 	r   c                 .    t         j                  |        y r   )r   r   rH   s    r   parentChangedzGraphicsItem.parentChanged  s    !!$'r   c                    t        | d      sy | j                          | j                          | j                         }d }| j                  | j	                         }||u ry |_t        |d      rdnd}d| d| j
                  fd| d| j                  ffD ]!  \  }}	 t        ||      j                  |       # d | _        |t        |d      rK|j                  j                  | j
                         |j                  j                  | j                         nJ|j                  j                  | j
                         |j                   j                  | j                         t#        j$                  |      | _        | j                          | j                          | j'                  |       | j)                  ||       y # t        t        t        f$ r Y Cw xY w)Nr;   sigDeviceRangeChangedDevice sigRangeChangedTransformChanged)r2   rS   rI   rQ   r;   viewRangeChangedviewTransformChangedgetattr
disconnect	TypeErrorAttributeErrorrN   r   connectsigDeviceTransformChangedsigRangeChangedsigTransformChangedrC   rD   _replaceViewviewChanged)r   rX   oldViewr   signalslots         r   r   zGraphicsItem._updateView  s    t-. 	  
 *))+G7? !(2I!JXPRF$'x|"<d>S>S!T$'x/?"@$B[B[!\!^ GV,77= #'D t45**2243H3HI..66t7P7PQ $$,,T-B-BC((001J1JK")++d"3D!!#%%' 	'"w'1 "><@ s   GGGc                      y)zkCalled when this item's view has changed
        (ie, the item has been added to or removed from a ViewBox)N )r   rX   r   s      r   r   zGraphicsItem.viewChanged      r   c                     || }|j                         D ]H  }t        |t              r$|j                         |u s&|j	                          7| j                  ||       J y r   )r   r   r   rQ   r   r   )r   r   itemchilds       r   r   zGraphicsItem._replaceView  s[    <D__& 	2E%.##%0%%' !!'51	2r   c                      y)zh
        Called whenever the view coordinates of the ViewBox containing this item have changed.
        Nr   rH   s    r   r   zGraphicsItem.viewRangeChanged   r   r   c                     d| _         y)z
        Called whenever the transformation matrix of the view has changed.
        (eg, the view range has changed or the view was resized)
        Invalidates the viewRect cache.
        N)r=   rH   s    r   r   z!GraphicsItem.viewTransformChanged'  s      r   c                     | j                         }|1t        |d      r$|j                  d      r|j                  |        yyyy)z
        Inform this item's container ViewBox that the bounds of this item have changed.
        This is used by ViewBox to react if auto-range is enabled.
        NrK   rL   )rQ   r2   rK   itemBoundsChangedr^   s     r   informViewBoundsChangedz$GraphicsItem.informViewBoundsChanged3  sF    
  l ;PY@Z""4( A[ ;r   c                     | j                         D cg c]"  }| j                  ||j                               $ }}t        t        j
                  |      S c c}w )zTReturn the union of the shapes of all descendants of this item in local coordinates.)allChildItemsmapFromItemshaper   operatoradd)r   cshapess      r   childrenShapezGraphicsItem.childrenShape<  sH    :>:L:L:NOQ$""1aggi0OOhllF++ Ps   'Ac                     || }g }|j                         D ]3  }|j                  |       |j                  | j                  |             5 |S )z>Return list of the entire item tree descending from this item.)r   rd   extendr   )r   roottreechs       r   r   zGraphicsItem.allChildItemsA  sP    <D//# 	0BKKOKK**2./	0 r   c                 .    |i }|r|| _         yd| _         y)a  
        This method is called by exporters to inform items that they are being drawn for export
        with a specific set of options. Items access these via self._exportOptions.
        When exporting is complete, _exportOptions is set to False.
        NF)r<   )r   exportoptss      r   setExportModezGraphicsItem.setExportModeL  s#     <D#D  %Dr   c                 @    t        | d      r| j                         gS g S )NgetMenu)r2   r  )r   events     r   getContextMenuszGraphicsItem.getContextMenus_  s    #*4#;CCr   nodesreturnc                     t         )aa  Method to override to manually specify the SVG writer mechanism.

        Parameters
        ----------
        nodes
            Dictionary keyed by the name of graphics items and the XML
            representation of the the item that can be written as valid
            SVG.
        
        Returns
        -------
        tuple
            First element is the top level group for this item. The
            second element is a list of xml Elements corresponding to the
            child nodes of the item.
        None
            Return None if no XML is needed for rendering

        Raises
        ------
        NotImplementedError
            override method to implement in subclasses of GraphicsItem

        See Also
        --------
        pyqtgraph.exporters.SVGExporter._generateItemSvg
            The generic and default implementation

        )NotImplementedError)r   r  s     r   generateSvgzGraphicsItem.generateSvgb  s    B "!r   r   )F)6r)   r*   r+   r,   r   ry   r   rF   rI   rQ   rS   rV   r_   rf   ri   r   r   r   r   r   r   r   r   r   r   r   r   rh   r   r   rM   r   r   r]   r   r   r   r   r   r   r   r   r   r   r   r   r  dictr7   r   r   rw   listr  r   r   r   r   r   (   s   	 "#h ". 4(
)
4Y)xF:: 	 2>2=2:	R8(:(xF	2 ),
%&D!"W%!" 
%g./	0!"r   )__all__r   rC   collectionsr   	functoolsr   mathr   typingr   xml.etree.ElementTreer   r   r
   r   r   r   Qtr   r   r   r   objectr   r   r   r   <module>r     sK   
   #    )  )  2 2
+ *[	"6 [	"r   