
    e!b                         d dl 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lm	Z	  G d d      Z
 G d	 d
      Z G d d      Z G d d      Z e       Zy)    N   )	functions   )	Parameter)ActionGroupParameterc                       e Zd ZdZy)PARAM_UNSETz9Sentinel value for detecting parameters with unset valuesN)__name__
__module____qualname____doc__     E/usr/lib/python3/dist-packages/pyqtgraph/parametertree/interactive.pyr	   r	      s    Cr   r	   c                       e Zd ZdZ	 dZ	 dZy)
RunOptionsactionchangedchangingN)r
   r   r   	ON_ACTION
ON_CHANGEDON_CHANGINGr   r   r   r   r      s$    I J Kr   r   c                        e Zd ZU dZeed<   eed<   dd fd
Zd Zd Zd	 Z	d
 Z
ddZddZd Zd Zd Zd Zd Zd Zd Z xZS )InteractiveFunctionaZ  
    ``interact`` can be used with regular functions. However, when they are connected to
    changed or changing signals, there is no way to access these connections later to
    i.e. disconnect them temporarily. This utility class wraps a normal function but
    can provide an external scope for accessing the hooked up parameter signals.
    r
   r   N)closuresc                    t         |           i | _        || _        || _        |i }|| _        d| _        d| _        i | _        t        j                  | |d       y)a  
        Wraps a callable function in a way that forwards Parameter arguments as keywords

        Parameters
        ----------
        function: callable
            Function to wrap
        closures: dict[str, callable]
            Arguments that shouldn't be constant, but can't be represented as a parameter.
            See the rst docs for more information.
        extra: dict
            extra keyword arguments to pass to ``function`` when this wrapper is called
        NFr   )updated)super__init__
parametersextrafunctionr   _disconnectedparametersNeedRunKwargsparameterCache	functoolsupdate_wrapper)selfr"   r   r!   	__class__s       r   r   zInteractiveFunction.__init__.   sc     	
 H "',$  	  x<r   c                 H   | j                   r | j                  di | | j                  j                         }|j	                  | j
                         | j                  j                         D ]  \  }} |       ||<     |j                  di |  | j                  di |S )z
        Calls ``self.function``. Extra, closures, and parameter keywords as defined on
        init and through :func:`InteractiveFunction.setParams` are forwarded during the
        call.
        r   )	r$   _updateParametersFromRunKwargsr!   copyupdater%   r   itemsr"   )r(   kwargs	runKwargskkvvs        r   __call__zInteractiveFunction.__call__K   s     ''/D//9&9JJOO%	,,-mm))+ 	!FBDIbM	!	"6"t}})y))r   c                 >    || j                   |j                         <   y)z
        This function is connected to ``sigChanged`` of every parameter associated with
        it. This way, those parameters don't have to be queried for their value every
        time InteractiveFunction is __call__'ed
        N)r%   name)r(   paramvalues      r   updateCachedParameterValuesz/InteractiveFunction.updateCachedParameterValues[   s     -2EJJL)r   c                    | j                         }	 t        |      j                  | j                        D ]#  }| j                  |   j	                  ||          % 	 |s| j                          	 t        |      t        | j                        z  D ]  }||   | j                  |<    y# |s| j                          w w xY w)z`
        Updates attached params from __call__ without causing additional function runs
        N)
disconnectsetintersectionr    setValue	reconnectr!   )r(   r/   wasDisconnectedkwargextraKeys        r   r+   z2InteractiveFunction._updateParametersFromRunKwargsc   s    
 //+	!V11$//B ?&//u>? # Fc$**o5 	4H#)(#3DJJx 	4 #  #s   A
B) )B>c                     |j                   j                  | j                         |j                  |j                   fD ]"  }t	        j                  || j
                         $ y N)sigValueChangedr:   r8   sigValueChangingfnrunFromChangedOrChanging)r(   r6   signals      r   _disconnectParameterz(InteractiveFunction._disconnectParameters   sR    (()I)IJ--u/D/DE 	AFMM&$"?"?@	Ar   c                 4   |r| j                          |D ]  }|| j                  |j                         <   |j                  j	                  | j
                         |j                         r|j                         nd| j                  |j                         <    y)a  
        Binds a new set of parameters to this function. If ``clearOld`` is *True* (
        default), previously bound parameters are disconnected.

        Parameters
        ----------
        params: Sequence[Parameter]
            New parameters to listen for updates and optionally propagate keywords
            passed to :meth:`__call__`
        clearOld: bool
            If ``True``, previously hooked up parameters will be removed first
        N)	removeParametersr    r5   rD   connectr8   hasValuer7   r%   )r(   paramsclearOldr6   s       r   hookupParametersz$InteractiveFunction.hookupParametersx   sz     !!# 	\E,1DOOEJJL)!!))$*J*JKAFAQW[D

-		\r   c                     | j                   j                         D ]  }| j                  |        | j                   j                          |r| j                  j                          yy)z
        Disconnects from all signals of parameters in ``self.parameters``. Also,
        optionally clears the old cache of param values
        N)r    valuesrI   clearr%   )r(   
clearCacheps      r   rK   z$InteractiveFunction.removeParameters   sZ    
 '') 	)A%%a(	) 	%%' r   c                     | j                   ry | j                  }d| _        	  | di |j                         |i}|| _        |S # || _        w xY w)NFr   )r#   r$   r5   )r(   r6   r7   oldPropagaterets        r   rG   z,InteractiveFunction.runFromChangedOrChanging   sY     33',$	8/%**,./C+7D(
 ,8D(s   A 	Ac                 ,    | j                   ry  | di |S )Nr   r#   r(   r/   s     r   runFromActionz!InteractiveFunction.runFromAction   s    ~f~r   c                 ,    | j                   }d| _         |S )zd
        Simulates disconnecting the runnable by turning ``runFrom*`` functions into no-ops
        TrZ   r(   oldDisconnects     r   r:   zInteractiveFunction.disconnect   s     **!r   c                 ,    | j                   }|| _         |S )z
        Sets the disconnected state of the runnable, see :meth:`disconnect` and
        :meth:`reconnect` for more information
        rZ   )r(   disconnectedr_   s      r   setDisconnectedz#InteractiveFunction.setDisconnected   s    
 **)r   c                 ,    | j                   }d| _         |S )zISimulates reconnecting the runnable by re-enabling ``runFrom*`` functionsFrZ   r^   s     r   r>   zInteractiveFunction.reconnect   s    **"r   c           	          t        |       j                   d| j                  j                   dt        t	        |              S )Nz(`<z>`) at )typer
   r"   hexidr(   s    r   __str__zInteractiveFunction.__str__   s8    t*%%&c$--*@*@)ARPTXXXr   c           	          t        |       dt        | j                         dt        | j                         dt        | j                         z   S )Nz with keys:
parameters=z, extra=z, closures=)strlistr    r!   r   rh   s    r   __repr__zInteractiveFunction.__repr__   sT    I t/0 1$**%& 'T]]+,. .	
r   )NT)T)r
   r   r   r   rk   __annotations__r   r3   r8   r+   rI   rP   rK   rG   r\   r:   rb   r>   ri   rm   __classcell__)r)   s   @r   r   r   "   sa     M-1 =:* 24 A
\*
(
Y
r   r   c                      e Zd Zej                  ZdZdZdZdZ	 e
dd      Zg dZd Zd Zej                   d	        Zdeeeeeed
dZ ej*                  e      d        Zd ZddZd Zed        Zd Zd ZddZd Zd Z d Z!d Z"d Z#y)
InteractorNTr   Run)re   defaultName)
runOptionsparenttitleFormatnestexistOkrunActionTemplatec                 (     | j                   di | y)z
        Initializes an Interactor with initial keyword arguments which can be anything
        accepted by :meth:`setOpts`
        Nr   setOptsr[   s     r   r   zInteractor.__init__   s    
 	vr   c                    | j                         }t        |      }t        |      j                  |      }|rt        d| d|       i }i }|j	                         D ]  \  }}||   ||<   |||<    | j
                  j                  |       |S )a[  
        Overrides the default options for this interactor.

        Note! This method should only be used if you spawn your own Interactor; do not
        call it on ``defaultInteractor``. Instead, use ``defaultInteractor.optsContext``,
        which is guaranteed to revert to the default options when the context expires.

        Parameters
        ----------
        opts
            Keyword arguments to override the default options

        Returns
        -------
            dict of previous options that were overridden. This is useful for resetting
            the options afterward.
        zUnrecognized options: z. Must be one of: )getOptsr;   
differenceKeyErrorr.   __dict__r-   )	r(   optsoldOptsallowederrorstoReturntoUser1   r2   s	            r   r|   zInteractor.setOpts   s    $ ,,.g,T%%g.3F8;MgYWXXjjl 	FB"2;HRLE"I	 	U#r   c              +   \   K    | j                   di |}d  | j                   di | yw)z
        Creates a new context for ``opts``, where each is reset to the old value
        when the context expires

        Parameters
        ----------
        opts:
            Options to set, must be one of the keys in :attr:`_optNames`
        Nr   r{   )r(   r   r   s      r   optsContextzInteractor.optsContext  s/      $,,&&ws   *,)ignoresrt   ru   rv   rw   ry   rx   c                @   |t         uri | j                  |}t               }
| j                  D ci c]  }|
|   t         us||
|    }} | j                  di |}~~~~~~| j                  |      } | j                  |j                  fi |	}|j                  dg       }|D cg c]  }|d   	 }}| j                  ||      }|g }t        |      t        |j                        z   }t        |      t        |      z  }|D ]@  }||j                  |         d   }||j                  vs)|t         us2||j                  |<   B |D cg c]4  }|d   t         u r'|d   |j                  vr|d   |j                  vr|d   6 }}|r$ | j                  di | t        d| d| d      g }|D cg c]	  }||vs| }}|D ]=  }||j                  |         }| j!                  |||      }|-|j#                  |       ? |j%                  |       t&        j(                  | j*                  v r5| j-                  |||j/                  d            }|r|j#                  |       | j0                  r|n|} | j                  di | |S c c}w c c}w c c}w c c}w )	a   
        Interacts with a function by making Parameters for each argument.

        There are several potential use cases and argument handling possibilities
        depending on which values are passed to this function, so a more detailed
        explanation of several use cases is provided in the "Interactive Parameters" doc.

        if any non-defaults exist, a value must be provided for them in ``overrides``. If
        this value should *not* be made into a parameter, include its name in ``ignores``.

        Parameters
        ----------
        function: Callable
            function with which to interact. Can also be a :class:`InteractiveFunction`,
            if a reference to the bound signals is required.
        runOptions: ``GroupParameter.<RUN_ACTION, CHANGED, or CHANGING>`` value
            How the function should be run, i.e. when pressing an action, on
            sigValueChanged, and/or on sigValueChanging
        ignores: Sequence
            Names of function arguments which shouldn't have parameters created
        parent: GroupParameter
            Parent in which to add argument Parameters. If *None*, a new group
            parameter is created.
        titleFormat: str or Callable
            title of the group sub-parameter if one must be created (see ``nest``
            behavior). If a function is supplied, it must be of the form (str) -> str
            and will be passed the function name as an input
        nest: bool
            If *True*, the interacted function is given its own GroupParameter,
            and arguments to that function are 'nested' inside as its children.
            If *False*, function arguments are directly added to this parameter
            instead of being placed inside a child GroupParameter
        runActionTemplate: dict
            Template for the action parameter which runs the function, used
            if ``runOptions`` is set to ``GroupParameter.RUN_ACTION``. Note that
            if keys like "name" or "type" are not included, they are inferred
            from the previous / default ``runActionTemplate``. This allows
            items that should only be set per-function to exist here, like
            a ``shortcut`` or ``icon``.
        existOk: bool
            Whether it is OK for existing parameter names to bind to this function.
            See behavior during 'Parameter.insertChild'
        overrides:
            Override descriptions to provide additional parameter options for each
            argument. Moreover, extra parameters can be defined here if the original
            function uses ``**`` to consume additional keyword arguments. Each
            override can be a value (e.g. 5) or a dict specification of a
            parameter (e.g. dict(type='list', limits=[0, 10, 20]))
        childrenr5   r7   zCannot interact with `z#` since it has required parameters z, with no default or closure values provided.tipr   )r	   ry   locals_optionNamesr|   _toInteractiveFunctionfunctionToParameterDictr"   pop_resolveFunctionGrouprl   r   r;   indexr!   
ValueErrorresolveAndHookupParameterChildappendrP   r   r   rt   _resolveRunActiongetrw   )r(   r"   r   rt   ru   rv   rw   ry   rx   	overrideslocsr1   r   r   funcDictr   chchNames	funcGrouprecycleNamesr5   r7   missingChildren	useParamsn
checkNames	childOptschildr   retValues                                 r   interactzInteractor.interact  s   ~ K/ O4#9#9 O=N Ox'+'8'8XDHK<WDHXX$,,&&T7F<M..x8/4//0A0AOYO<<
B/(01"2f:11..xB	 ?Gw-$x'8'8"99 7|c'l2  	-DW]]401':E8>>)e;.F',t$	- 
'{k)6
("3"336
(..0	 vJ
 
  DLL#7#(
2U"##OQ 
 	!(=AAW,<a=
= 	(D t!45I77	9hWE   '		( 	!!),4??2++HieATUF  ( $		9yw w Y 2 
$ >s#   JJ(J9J4	J>Jc                 (     | j                   |fi |S rC   )r   )r(   r"   r/   s      r   r3   zInteractor.__call__  s    t}}X000r   c                       fd}|S )z
        Calls :meth:`interact` and returns the :class:`InteractiveFunction`.

        Parameters
        ----------
        kwargs
            Keyword arguments to pass to :meth:`interact`
        c                 d    t        | t              st        |       }  j                  | fi  | S rC   )
isinstancer   r   )r"   r/   r(   s    r   	decoratorz&Interactor.decorate.<locals>.decorator  s0    h(;<.x8DMM(-f-Or   r   )r(   r/   r   s   `` r   decoratezInteractor.decorate  s    	 r   c                 b    | j                   }t        |t              }||r|s|S |r|S  ||      S )aO  
        Converts a function name to a title based on ``self.titleFormat``.

        Parameters
        ----------
        name: str
            Name of the function
        forwardStringTitle: bool
            If ``self.titleFormat`` is a string and ``forwardStrTitle`` is True,
            ``self.titleFormat`` will be used as the title. Otherwise, if
            ``self.titleFormat`` is *None*, the name will be returned unchanged.
            Finally, if ``self.titleFormat`` is a callable, it will be called with
            the name as an input and the output will be returned
        )rv   r   rk   )r(   r5   forwardStringTitlerv   isStrings        r   _nameToTitlezInteractor._nameToTitle  s?     &&k3/84FK4  r   c                    | j                   }| j                  rmt        j                  di |}| j                   r'| j                   j	                  || j
                        }|j                  j                  |j                         |S )z
        Returns parent parameter that holds function children. May be ``None`` if
        no top parent is provided and nesting is disabled.
        rx   r   )	ru   rw   r   createaddChildrx   sigActivatedrL   r\   )r(   functionDictinteractiveFunctionr   s       r   r   z Interactor._resolveFunctionGroup  sl    
 KK	99!((8<8I{{ KK00DLL0Q	""**+>+L+LMr   c                     t        | t              r| S t        |       }t        j                  |       s| n| j                  }t        |d      r|j                  j                  |       |S |g|_        |S )NinteractiveRefs)r   r   inspectismethod__func__hasattrr   r   )r"   interactiverefOwners      r   r   z!Interactor._toInteractiveFunction  sq    h 34O
 *(3#*#3#3H#=88CTCT8./$$++K8  )4}H$r   c                 t   |st        j                  di |}n|j                  || j                        }t        j
                  | j                  v r%|j                  j                  |j                         t        j                  | j                  v r%|j                  j                  |j                         |S )Nr   r   )r   r   r   rx   r   r   rt   rD   rL   rG   r   rE   )r(   functionGroupr   r   r   s        r   r   z)Interactor.resolveAndHookupParameterChild  s     $$1y1E!**9dll*KE  DOO3!!))*=*V*VW!!T__4""**+>+W+WXr   c                 <   t        |t              r|j                  d       d }|S | j                  |j                  |      }t        j                  di |}|j                  j                  |j                         |r|j                  || j                         |S )NT)visibler   r   )r   r   setButtonOpts_makePopulatedActionTemplater
   r   r   r   rL   r\   r   rx   )r(   r   r   functionTipr   
createOptss         r   r   zInteractor._resolveRunAction  s    m%9:'''5E  ::#,,kJ $$2z2E&&':'H'HI&&udll&Cr   c                     | j                   j                         }|j                  dd      }| j                  r|n|}|j	                  d|       |r|j	                  d|       |S )Nrs   rr   r5   r   )ry   r,   r   rw   
setdefault)r(   functionNamer   r   rs   r5   s         r   r   z'Interactor._makePopulatedActionTemplate  s\    ++002
 nn]E:"ii{\fd+!!%5r   c           	         g }|j                   }t        di | j                  |      ddi}t        |d||      }| j                  | j	                  |d      |d<   t        j                  |      j                  }|j                  rKt        j                  |j                        \  }}	|r'|j                  d|       |d	   j                  d|       t        |      }
|j                         D cg c]  }|j                   }}t
        j                  j                   }t
        j                  j"                  }||v r(|
d
= |D cg c]	  }||
vs| }}|
j%                  |       ||v r|
|j'                  |      = |
D ]G  }|j)                  |      }| j+                  |||j)                  |i             }|j-                  |       I |S c c}w c c}w )zJ
        Converts a function into a list of child parameter dicts
        r   F_actiongroup)r5   re   r   buttonT)r   titler   r   r   )r
   dictr   rv   r   r   	signaturer    r   pydocsplitdocr   rl   rR   kindr   VAR_POSITIONALVAR_KEYWORDextendr   r   createFunctionParameterr   )r(   r"   r   r   r5   btnOptsout
funcParamssynopsis_r   rU   parameterKinds_positional_keywordr   notInSignaturer6   pgDicts                      r   r   z"Interactor.functionToParameterDict  s      P::4@P%P>HWU',,Td,KCL&&x0;;
..)9)9:KHauh/H((9 *%
*4*;*;*=>Q!&&>>''66$$00~%
 2)2JAaz6IaJNJn-.( >//<= 	$DNN4(E11$y}}TSU?VWFOOF#		$
 
- ? Ks   1G
	GGc                    |=|j                   |j                  ur%|j                   }|t        |      j                  d}ni }|j	                         }t        |t              sd|i}|j                  |       ||d<   |j                  dt               | j                  !|j                  d| j                  |             |j                  dt        |d         j                         |S )a~  
        Constructs a dict ready for insertion into a group parameter based on the
        provided information in the ``inspect.signature`` parameter, user-specified
        overrides, and true parameter name. Parameter signature information is
        considered the most "overridable", followed by documentation specifications.
        User overrides should be given the highest priority, i.e. not usurped by
        parameter default information.

        Parameters
        ----------
        name : str
            Name of the parameter, comes from function signature
        signatureParameter : inspect.Parameter
            Information from the function signature, parsed by ``inspect``
        overridesInfo : dict
            User-specified overrides for this parameter. Can be a dict of options
            accepted by :class:`~pyqtgraph.parametertree.Parameter` or a value
        )r7   re   r7   r5   r   re   )defaultemptyre   r
   r,   r   r   r-   r   r	   rv   r   )r(   r5   signatureParameteroverridesInfor   signatureDictr   s          r   r   z"Interactor.createFunctionParameter6  s    ( *"**2D2J2JJ
 )00G&-tG}7M7MNMM##%-.$m4Mm$ v 	';/ 'gt'8'8'>?&$vg"7"@"@Ar   c                 (    d| j                          S )NzInteractor with opts: )r~   rh   s    r   ri   zInteractor.__str__g  s    ''788r   c                     t        |       S rC   )rk   rh   s    r   rm   zInteractor.__repr__j  s    4yr   c                 V    | j                   D ci c]  }|t        | |       c}S c c}w rC   )r   getattr)r(   attrs     r   r~   zInteractor.getOptsm  s(    6:6G6GHdgdD))HHHs   &)F) N)$r
   r   r   r   r   rt   ru   rv   rw   rx   r   ry   r   r   r|   
contextlibcontextmanagerr   r	   r   r&   wrapsr3   r   r   r   staticmethodr   r   r   r   r   r   ri   rm   r~   r   r   r   rq   rq      s    %%JFKDG(>L@    $ %B Y__X1 1$!0   ,\/b9Ir   rq   )r   r&   r   r   r   r   rF   r   parameterTypesr   r	   r   r   rq   r   r   r   r   <module>r      sU          0D D &i
 i
X`I `IF <r   