
XTc           @   s  d  d l  Z  d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l m Z d e  j	 f d     YZ
 d e
 f d     YZ d e f d     YZ d	 e f d
     YZ d e f d     YZ d e f d     YZ d e f d     YZ d e
 f d     YZ e j e Z d e f d     YZ d e j f d     YZ e e  Z e e j e <e j j e j  e j d e  e j d e  e j d e  e j d e  e j d e  d S(   iN(   t   bisect_rightt
   BaseWidgetc           B   s)   e  Z d  Z d   Z d   Z d   Z RS(   s   
    The BaseWidget is the simplest possible widget that all other widgets
    must subclass. It handles tracking its owning form and the styling that
    should be applied.
    c         C   s[   | j  j d | |  _ | |  _ | |  _ t j j |  |  t j |  j	 |  j
  |  _ d  S(   Nt   .(   t	   __class__t   __name__t	   __style__t   namet   formt   spyralt   Viewt   __init__t   Rectt   post   sizet   mask(   t   selfR   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR
      s
    		c         C   s   |  j    t j j |   d S(   s   
        Called when the Widget is changed; since Widget's masks are a function
        of their component widgets, it needs to be notified.
        N(   t   _recalculate_maskR   R	   t   _changed(   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR      s    
c         C   s&   t  j |  j |  j |  j  |  _ d S(   sZ   
        Recalculate this widget's mask based on its size, position, and padding.
        N(   R   R   R   R   t   paddingR   (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR      s    (   R   t
   __module__t   __doc__R
   R   R   (    (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR   
   s   		t   MultiStateWidgetc           B   s   e  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 e e e  Z e e  Z e e e
  Z e e	 e  Z e e e  Z e e e  Z d   Z RS(   sn  
    The MultiStateWidget is an abstract widget with multiple states. It should
    be subclassed and implemented to have different behavior based on its
    states.

    In addition, it supports having a Nine Slice image; it will cut a given
    image into a 3x3 grid of images that can be stretched into a button. This
    is a boolean property.

    :param form: The parent form that this Widget belongs to.
    :type form: :class:`Form <spyral.Form>`
    :param str name: The name of this widget.
    :param states: A list of the possible states that the widget can be in.
    :type states: A ``list`` of ``str``.
    c         C   sx   | |  _  |  j  d |  _ d  |  _ t j |  | |  d d g |  _ i  |  _ d |  _ t	 j
 |   |  _ d |  j _ d  S(   Ni    t   baset   content(   i    i    (   t   _statest   _statet   Nonet   buttonR   R
   t   layerst   _imagest   _content_sizeR   t   Spritet   layer(   R   R   R   t   states(    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR
   7   s    				c         C   s   x| |  j  D]q } |  j r^ |  j |  j } t j |  j |  } t j j | |  |  j	 | <q
 t j |  j |  |  j	 | <q
 W|  j	 |  j
 |  j _ t j |  j |  j j  |  _ |  j   d S(   s   
        Recreates the cached images of this widget (based on the
        **self._image_locations** internal variabel) and sets the widget's image
        based on its current state.
        N(   R   t   _nine_slicet   _paddingR   R   t   Imaget   _image_locationst   imaget   render_nine_sliceR   R   R   R   R   R   R   t   _on_state_change(   R   t   stateR   t   nine_slice_image(    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _render_imagesD   s    	!c      	   C   s   |  j  } | |  _ |  j  | k r t j d d d |  d |  j d |  j    } |  j j d i |  j j j	 d 6|  j
 d 6|  n  |  j | |  j _ t j |  j |  j j  |  _ |  j   d  S(   NR   t   changedt   widgetR   t   values%   form.%(form_name)s.%(widget)s.changedt	   form_name(   R.   R   R   t   EventR   t
   _get_valuet   scenet   _queue_eventR   R   R   R   R   R&   R   R   R   R   R(   (   R   R)   t	   old_valuet   e(    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt
   _set_stateU   s    		-
c         C   s   |  j  S(   sl   
        Returns the current value of this widget; defaults to the ``state`` of
        the widget.
        (   R   (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR1   b   s    c         C   s   |  j  S(   s   
        This widget's state; when changed, a form.<name>.<widget>.changed
        event will be triggered. Represented as a ``str``.
        (   R   (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt
   _get_statei   s    c         C   s   | |  _  |  j   d  S(   N(   R"   R+   (   R   t
   nine_slice(    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _set_nine_slicep   s    	c         C   s   |  j  S(   ss   
        The :class:`Image <spyral.Image>` that will be nine-sliced into this
        widget's background.
        (   R"   (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _get_nine_slicet   s    c         C   sA   t  | t j  r | |  _ n t j | |  |  _ |  j   d  S(   N(   t
   isinstanceR   t   Vec2DR#   R+   (   R   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _set_padding{   s    c         C   s   |  j  S(   s  
        A :class:`Vec2D <spyral.Vec2D>` that represents the horizontal and
        vertical padding associated with this button. Can also be set with a
        ``int`` for equal amounts of padding, although it will always return a
        :class:`Vec2D <spyral.Vec2D>`.
        (   R#   (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _get_padding   s    c         C   s   | |  _  |  j   d S(   s   
        The size of the content within this button, used to calculate the mask.
        A :class:`Vec2D <spyral.Vec2D>`

        ..todo:: It's most likely the case that this needs to be refactored into
        the mask property, since they're probably redundant with each other.
        N(   R   R+   (   R   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _set_content_size   s    	c         C   s   |  j  S(   N(   t   _get_content_size(   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR@      s    c         C   s   d S(   sI   
        A function triggered whenever this widget changes size.
        N(    (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _on_size_change   s    c         C   s   |  j  S(   sw   
        Defines an `anchor point <anchors>` where coordinates are relative to
        on the widget. ``str``.
        (   t   _anchor(   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _get_anchor   s    c         C   s>   |  j  d  k	 r* | |  j  _ | |  j _ n  t j |  |  d  S(   N(   R   R   t   anchort   _text_spriteR   t   _set_anchor(   R   RD   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRF      s    c         C   s   | j  d d  |  _ t |  j t j  sH t j |  j |  j  |  _ n  | j  d t  |  _ i  |  _ x. |  j D]# } | j  d | f  |  j | <qp Wt j	 j
 |  |  d S(   s   
        Applies the *properties* to this scene. This is called when a style
        is applied.

        :param properties: a mapping of property names (strings) to values.
        :type properties: ``dict``
        R   i   R8   s   image_%sN(   t   popR#   R;   R   R<   t   FalseR"   R%   R   R	   t   __stylize__(   R   t
   propertiesR)   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRI      s    	!(   R   R   R   R
   R+   R6   R1   R7   R9   R:   R=   R>   R?   R@   RA   RC   RF   t   propertyRD   R.   R   R8   R)   t   content_sizeRI   (    (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR   '   s,   															t   ButtonWidgetc           B   s   e  Z d  Z d d  Z d   Z d   Z d   Z d   Z e e  Z	 e e e  Z
 d   Z d   Z d	   Z d
   Z d   Z d   Z d   Z d   Z d   Z d   Z RS(   s  
    A ButtonWidget is a simple button that can be pressed. It can have some
    text. If you don't specify an explicit width, then it will be sized
    according to it's text.

    :param form: The parent form that this Widget belongs to.
    :type form: :class:`Form <spyral.Form>`
    :param str name: The name of this widget.
    :param str text: The text that will be rendered on this button.
    t   Okayc      
   C   sS   t  j |  | | d d d d d d g  t j |   |  _ d |  j _ | |  _ d  S(   Nt   upt   downt   down_focusedt   down_hoveredt
   up_focusedt
   up_hoveredR   (   R   R
   R   R   RE   R    t   text(   R   R   R   RU   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR
      s    c         C   s   d |  j  k r d Sd Sd S(   sQ   
        Whether or not this widget is currently ``"up"`` or ``"down"``.
        RO   RP   N(   R   (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR1      s    c         C   s   |  j  S(   s=   
        The text rendered on this button (``str``).
        (   t   _text(   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt	   _get_text   s    c         C   sD   | |  _  |  j j |  j   |  j _ |  j j j |  _ |  j   d  S(   N(   RV   t   fontt   renderRE   R&   R   R   R+   (   R   RU   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt	   _set_text   s    	c         C   s;   t  j j |  j |  j d d |  j d d  |  j _ d S(   sI   
        A function triggered whenever this widget changes size.
        i    i   i   N(   R   t   utilt   _anchor_offsetRB   R#   RE   R   (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR(      s    c      	   C   s   |  j  j d  r |  j  j d d  |  _  t j d d d |  d |  j d |  j    } |  j j d i |  j j	 j
 d	 6|  j d 6|  n  d
 S(   sV   
        The function called when the mouse is released while on this widget.
        RP   RO   R   t   clickedR-   R   R.   s%   form.%(form_name)s.%(widget)s.clickedR/   N(   R)   t
   startswitht   replaceR   R0   R   R1   R2   R3   R   R   R   (   R   t   eventR5   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _handle_mouse_up   s    -c         C   s1   |  j  j d  r- |  j  j d d  |  _  n  d S(   sx   
        The function called when the mouse is pressed while on this widget.
        Fires a ``clicked`` event.
        RO   RP   N(   R)   R^   R_   (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _handle_mouse_down  s    c         C   s.   d |  j  k r* |  j  j d d  |  _  n  d S(   sW   
        The function called when this button is no longer being hovered over.
        t   _hoveredt    N(   R)   R_   (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _handle_mouse_out  s    c         C   s2   d |  j  k r. |  j  j d d  d |  _  n  d S(   sV   
        The function called when the mouse starts hovering over this button.
        Rc   t   _focusedRd   N(   R)   R_   (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _handle_mouse_over  s    c         C   s   d S(   sR   
        The function called when the mouse moves while over this button.
        N(    (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _handle_mouse_motion  s    c         C   s%   |  j  d k r! |  j  d 7_  n  d S(   s8   
        Applies the focus state to this widget
        RO   RP   Rf   N(   s   ups   down(   R)   (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _handle_focus#  s    c         C   s.   |  j  d k r* |  j  j d d  |  _  n  d S(   s=   
        Removes the focused state from this widget.
        RS   RQ   Rf   Rd   N(   s
   up_focuseds   down_focused(   R)   R_   (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _handle_blur*  s    c         C   s5   | j  t j j t j j f k r1 |  j |  n  d S(   se   
        When the enter or space key is pressed, triggers this button being
        pressed.
        N(   t   keyR   t   keyst   entert   spaceRb   (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _handle_key_down1  s    !c         C   s5   | j  t j j t j j f k r1 |  j |  n  d S(   sf   
        When the enter or space key is pressed, triggers this button being
        released.
        N(   Rk   R   Rl   Rm   Rn   Ra   (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _handle_key_up9  s    !c         C   sD   t  j | j d    |  _ | j d d  |  _ t j |  |  d S(   s   
        Applies the *properties* to this scene. This is called when a style
        is applied.

        :param properties: a mapping of property names (strings) to values.
        :type properties: ``dict``
        RX   RU   t   ButtonN(   R   t   FontRG   RX   RV   R   RI   (   R   RJ   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRI   A  s    (   R   R   R   R
   R1   RW   RZ   R(   RK   R.   RU   Ra   Rb   Re   Rg   Rh   Ri   Rj   Ro   Rp   RI   (    (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRM      s$   

														t   ToggleButtonWidgetc           B   s,   e  Z d  Z d d  Z d   Z d   Z RS(   si  
    A ToggleButtonWidget is similar to a Button, except that it will stay down
    after it's been clicked, until it is clicked again.

    :param form: The parent form that this Widget belongs to.
    :type form: :class:`Form <spyral.Form>`
    :param str name: The name of this widget.
    :param str text: The text that will be rendered on this button.
    RN   c         C   s   t  j |  | | |  d  S(   N(   RM   R
   (   R   R   R   RU   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR
   X  s    c         C   s   d S(   sV   
        The function called when the mouse is released while on this widget.
        N(    (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRa   [  s    c         C   s^   |  j  j d  r- |  j  j d d  |  _  n- |  j  j d  rZ |  j  j d d  |  _  n  d S(   s6   
        Triggers the mouse to change states.
        RP   RO   N(   R)   R^   R_   (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRb   a  s    (   R   R   R   R
   Ra   Rb   (    (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRs   N  s   		t   CheckboxWidgetc           B   s   e  Z d  Z d   Z RS(   sc   
    A CheckboxWidget is identical to a ToggleButtonWidget, only it doesn't have
    any text.
    c         C   s   t  j |  | | d  d  S(   NRd   (   Rs   R
   (   R   R   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR
   p  s    (   R   R   R   R
   (    (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRt   k  s   t   RadioButtonWidgetc           B   s   e  Z d  Z d   Z RS(   s   
    A RadioButton is similar to a CheckBox, except it is to be placed into a
    RadioGroup, which will ensure that only one RadioButton in it's group is
    selected at a time.

    ..warning:: This widget is incomplete.
    c         C   s   t  j |  | | t  d  S(   N(   Rs   R
   t   _view_x(   R   R   R   t   group(    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR
   {  s    (   R   R   R   R
   (    (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRu   s  s   t   RadioGroupWidgetc           B   s   e  Z d  Z d d  Z RS(   su   
    Only one RadioButton in a RadioGroup can be selected at a time.

    ..warning:: This widget is incomplete.
    c         C   s   d  S(   N(    (   R   t   buttonst   selected(    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR
     s    N(   R   R   R   R   R
   (    (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRx   ~  s   t   TextInputWidgetc           B   s  e  Z d  Z d e dJ dJ d  Z d   Z d   Z d   Z d   Z	 d   Z
 dJ 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 e e e  Z e e e  Z e e e  Z e e e  Z e e e  Z d   Z d   Z  d   Z! e" j# j$ e" j# j% e" j# j& e" j# j' e" j# j( e" j# j) e" j# j* e" j# j+ e" j# j, e" j# j- e" j# j. e" j# j/ e" j# j0 e" j# j1 e" j# j2 e" j# j3 e" j# j4 e" j# j5 e" j# j6 e" j# j7 e" j# j8 e" j# j9 f Z: dK Z; dL e: Z< d9 dJ d:  Z= d9 dJ d;  Z> e? d<  Z@ e? d=  ZA e? d>  ZB e? d?  ZC d@   ZD dA   ZE dB   ZF dC   ZG dD   ZH dE   ZI dF   ZJ dG   ZK dH   ZL dI   ZM RS(M   s  
    The TextInputWidget is used to get text data from the user, through an
    editable textbox.

    :param form: The parent form that this Widget belongs to.
    :type form: :class:`Form <spyral.Form>`
    :param str name: The name of this widget.
    :param int width: The rendered width in pixels of this widget.
    :param str value: The initial value of this widget.
    :param bool default_value: Whether to clear the text of this widget the
                               first time it gains focus.
    :param int text_length: The maximum number of characters that can be entered
                            into this box. If ``None``, then there is no
                            maximum.
    :param set validator: A set of characters that are allowed to be printed.
                          Defaults to all regularly printable characters (which
                          does not include tab and newlines).
    Rd   c   	      C   sO  d \ |  _  |  _ t j |  | |  d d g |  _ |  j |  j f } t j |   |  _ d |  j _	 t j |   |  _
 | |  j
 _ d |  j
 _	 t j |   |  _ | |  j _ d |  j _	 t |  _ t |  j
 _ d |  _ t |  _ t |  _ t |  _ d |  _ |  j |  _ | |  _ | |  _ d |  _ | d |  j |  _  | |  _ t t j |  j j   |  _ |  j    t j! d d |  j f  |  j
 _" |  j
 j" j# |  j$  | d  k rt& t' t( j)  j* d   |  _+ n	 | |  _+ | d  k	 rt, |  | k  r| |  } n  d  |  _- | |  _. |  j/   |  j0 |  j _" t j1 j2 d	 |  j3 d
 |  j4 d  S(   Ni    R   R   s   content:aboveg        i   R   s   
	s   director.updateR2   (   i    i    (5   t	   box_widtht   _box_heightR   R
   R   R#   R   R   t   _backR    t   _cursorRD   RV   R   RH   Rf   t   visiblet   _selection_post
   _selectingt   _shift_was_downt   _mouse_is_downt   _cursor_timet   _cursor_blink_intervalt   default_valuet   _default_value_permanantRv   t   text_lengtht   intt   matht   ceilRX   t   linesizeR   R$   R&   t   fillt   _cursor_colorR   t   strt   sett   stringt	   printablet
   differencet	   validatort   lent   _valueR.   t   _render_backst   _image_plainR`   t   registert   _updateR2   (	   R   R   R   t   widthR.   R   R   R   t   child_anchor(    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR
     sN    										
!$			
c         C   sG   t  j |  j |  j |  j |  j |  j |  j |  j |  j  |  _ d S(   s   
        Forces a recomputation of the widget's mask, based on the position,
        internal boxes size, and the padding.
        N(   R   R   t   xR   t   yR|   R}   R   (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR     s     c         C   s   |  j  } |  j d | d } |  j d | d } t j |  j d  |  _ t j |  j d  |  _ |  j r t j	 j
 } | |  j | | f  |  _ | |  j | | f  |  _ n  d S(   sH   
        Recreates the nine-slice box used to back this widget.
        i   t   focusedt	   unfocusedN(   R#   R|   R}   R   R$   R%   R   t   _image_focusedR"   R&   R'   (   R   R   R   t   heightR'   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR     s    				c         C   s   | j  } | d d  |  _ | d t  |  _ i  |  _ | d  |  j d <| d  |  j d <| d d	  |  _ | d
 d  |  _ | d d  |  _ | d d  |  _ t	 j
 | d    |  _ t	 j j |  |  d S(   s   
        Applies the *properties* to this scene. This is called when a style
        is applied.

        :param properties: a mapping of property names (strings) to values.
        :type properties: ``dict``
        R   i   R8   t   image_focusedR   t   image_unfocusedR   t   cursor_blink_intervalg      ?t   cursor_colori    t   highlight_colori   i   t   highlight_background_colorRX   N(   i    i    i    (   i    i   i   (   i    i   i   (   RG   R#   RH   R"   R%   R   R   t   _highlight_colort   _highlight_background_colorR   Rr   RX   R	   RI   (   R   RJ   RG   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRI     s    		c         C   sd   g  |  _  d } xN t t |  j  d  D]3 } |  j j |  j |   d } |  j  j |  q) Wd S(   s   
        Compute and store the width for each substring in text. I.e., the first
        character, the first two characters, the first three characters, etc.
        i    i   N(   t   _letter_widthst   rangeR   R   RX   t   get_sizet   append(   R   t   running_sumt   index(    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _compute_letter_widths  s
    	 c      	   C   s   | t  |  j  k rP |  j | 7_ |  j j |  j  d } |  j j |  n) |  j |  | |  j | |  _ |  j   |  j   t j	 d d d |  d |  j
 d |  j  } |  j j d i |  j
 j j d 6|  j d 6|  d	 S(
   s   
        Insert the given *char* into the text at *position*.

        Also triggers a form.<name>.<widget>.changed event.
        i    R   R,   R-   R   R.   s%   form.%(form_name)s.%(widget)s.changedR/   N(   R   R   RX   R   R   R   R   t   _render_textR   R0   R   R2   R3   R   R   R   (   R   t   positiont   chart	   new_widthR5   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _insert_char  s    

c      	   C   s   | d	 k r | d } n  | t |  j  k r1 n% |  j |  |  j | |  _ |  j   |  j   |  j   t j d d d |  d |  j d |  j  } |  j	 j
 d i |  j j j d 6|  j d 6|  d	 S(
   s   
        Remove the characters from *position* to *end* within the text. If *end*
        is None, it removes only a single character.

        Also triggers a form.<name>.<widget>.changed event.
        i   R   R,   R-   R   R.   s%   form.%(form_name)s.%(widget)s.changedR/   N(   R   R   R   R   R   t   _render_cursorR   R0   R   R2   R3   R   R   R   (   R   R   t   endR5   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _remove_char!  s    


*c         C   s   | d |  j  |  j |  j } t |  j |  } | t |  j  k rS t |  j  S| r |  j | |  j | d } | |  j | d 8} | | d k r | d S| Sn d Sd S(   s   
        Given a mouse position, computes the closest index in the string.

        :returns: The index in the string (an ``int).
        i    i   i   N(   Rv   R   R#   R    R   R   R   (   R   t	   mouse_posR   R   t   diff(    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _compute_cursor_pos8  s    c         C   s   d |  _  t |  j _ d S(   s1   
        Stops the cursor from blinking.
        i    N(   R   t   TrueR   R   (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _stop_blinkingL  s    	c         C   s   |  j  S(   s   
        The current value of this widget, i.e, the text the user has input. When
        this value is changed, it triggers a ``form.<name>.<widget>.changed``
        event. A ``str``.
        (   R   (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR1   S  s    c      	   C   s   |  j  d  k	 rj t j d d d |  d |  j d |  } |  j j d i |  j j j d 6|  j	 d 6|  n  | |  _  |  j
   d |  _ |  j   |  j   d  S(	   NR   R,   R-   R   R.   s%   form.%(form_name)s.%(widget)s.changedR/   i    (   R   R   R   R0   R   R2   R3   R   R   R   R   t   _cursor_posR   R   (   R   R.   R5   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt
   _set_value[  s    
	
	
c         C   s   |  j  S(   sU   
        The current index of the text cursor within this widget. A ``int``.
        (   R   (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _get_cursor_posi  s    c         C   s!   | |  _  |  j   |  j   d  S(   N(   R   t   _move_rendered_textR   (   R   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _set_cursor_poso  s    	
c         C   sU   |  j  d k p3 |  j  d k	 o3 t |  j  |  j  k  } t |  |  j k } | oT | S(   s   
        Tests whether the given character is a valid one and that there is room
        for the character within the textbox.
        N(   R   R   R   R   R   R   (   R   R   t   valid_lengtht
   valid_char(    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt	   _validatet  s
    c         C   s   | |  _  |  j   d  S(   N(   R"   R   (   R   R8   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR9     s    	c         C   s   |  j  S(   sh   
        The :class:`Image <spyral.Image>` used to build the internal nine-slice
        image.
        (   R"   (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR:     s    c         C   s   | |  _  |  j   d  S(   N(   R#   R   (   R   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR=     s    	c         C   s   |  j  S(   st   
        A single ``int`` representing both the vertical and horizontal padding
        within this widget.
        (   R#   (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR>     s    c         C   s   |  j  S(   st   
        Defines an `anchor point <anchors>` where coordinates are relative to
        on the view. String.
        (   RB   (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRC     s    c         C   s8   | |  j  _ | |  j _ | |  j _ t j |  |  d  S(   N(   R~   RD   RV   R   R   RF   (   R   RD   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRF     s    c         C   s  |  j  ry|  j |  j k ryt |  j |  j f  \ } } |  j j |  j |   } |  j j |  j | | !d |  j } |  j j |  j |  } |  j j |  j |   d | j	 | j	 d } |  j |  r+|  j j |  j  d | j	 | j	 | j	 d } t
 j j | | | f d | | g  |  _ q|  j j |  j  d | j	 | j	 } t
 j j | | f d | g  |  _ n |  j j |  j  |  _ |  j   d S(   sF   
        Causes the text to be redrawn on the internal image.
        t   colori    i   t   rightN(   R   R   R   t   sortedRX   RY   R   R   R   R   R   R&   t   from_sequencet   _rendered_textR   (   R   t   startR   t   pret	   highlightt   postt
   pre_missedt   post_missed(    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR     s    %/2-''c         C   s  |  j  |  j } |  j  t |  j  } d } | |  j } | d k  rW |  j | 7_ n  | | |  j k r |  j | | |  j 7_ n  |  j |  j | k r | |  j k r | |  j |  _ n  |  j j   } | j |  j d f |  j |  j	 f  | |  j
 _ d S(   s   
        Offsets the text within the image. This could probably be reimplemented
        using the new cropping mechanism within Views.
        i   i    N(   R   t
   cursor_posR   R   Rv   R|   R   t   copyt   cropR}   RV   R&   (   R   R   t	   max_widtht   cursor_widthR   R&   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR     s    %c         C   sB   t  t |  j |  j |  j d  |  j  |  j _ d |  j _ d S(   s>   
        Moves the text cursor to the right position.
        i    N(	   t   mint   maxR   R   Rv   R|   R   R   R   (   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR     s    2t    R   t   ?t   !t   @t   #t   $t   %t   ^t   &t   *t   (t   )t   +t   =t   {t   }t   [t   ]t   ;t   :t   <t   >t   ,t   /s   \t   |t   "t   't   ~t   `s   	i    c         C   s^   | d k r t |  } n  x< t | | | ! D]' \ } } | |  j k r/ | | d Sq/ W| S(   sG   
        Returns the index of the next word in the given text.
        i   N(   R   R   t	   enumeratet   _non_skippable_keys(   R   RU   R   R   R   t   letter(    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _find_next_word  s     c         C   sd   | d k r t |  } n  xB t t | | | !  D]' \ } } | |  j k r5 | | d Sq5 W| S(   sK   
        Returns the index of the previous word in the given text.
        i   N(   R   R   R   t   reversedR   (   R   RU   R   R   R   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _find_previous_word  s    &c         C   s   |  j  rC t |  j |  j f  \ } } | |  _ |  j | |  nV | r |  j } |  j |  j |  j t |  j   } |  j | |  n |  j |  j  d S(   s   
        Deletes the currently selected text, or the text at the current
        cursor position. If *by_word* is specified, the rest of the word is
        deleted too.
        N(	   R   R   R   R   R   R   R.   R   R   (   R   t   by_wordR   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _delete  s    			$c         C   s   |  j  rC t |  j |  j f  \ } } | |  _ |  j | |  n |  j sO nu | r |  j |  j d |  j d  } |  j } | |  _ |  j | |  n+ |  j r |  j d 8_ |  j |  j  n  d S(   s   
        Deletes the currently selected text, or the character behind the current
        cursor position. If *by_word* is specified, the beginning of the word is
        deleted too.
        i    i   N(   R   R   R   R   R   R   R   R.   (   R   R   R   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt
   _backspace  s    						c         C   sD   | r' |  j  |  j d |  j  |  _ n t |  j d d  |  _ d S(   s   
        Moves the cursor left one character; if *by_word* is selected, then the
        cursor is moved to the start of the current word.
        i    i   N(   R   R.   R   R   (   R   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _move_cursor_left(  s    !c         C   sV   | r0 |  j  |  j |  j t |  j   |  _ n" t |  j d t |  j   |  _ d S(   s   
        Moves the cursor right one character; if *by_word* is selected, then the
        cursor is moved to the end of the current word.
        i   N(   R   R.   R   R   R   (   R   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   _move_cursor_right2  s    *c         C   sY   |  j  rU |  j | 7_ |  j |  j k rU |  j |  j 8_ |  j j |  j _ qU n  d S(   s=   
        Make the cursor blink every blink_interval.
        N(   Rf   R   R   R   R   (   R   t   delta(    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR   <  s
    	c         C   sB  | j  } | j } | t j j @p= | t j j t j j f k } |  j oM | } | |  _ | s~ | r |  j	 r | t
 j k r |  j |  _ t |  _	 n  | t j j k r |  j | t j j @ n4| t j j k r |  j | t j j @ n| t j j k rd |  _ n | t j j k r3t |  j  |  _ n | t j j k r_|  j | t j j @ n | t j j k r|  j | t j j @ nk | t
 j k r|  j	 r|  j   n  t | j   } |  j |  r|  j |  j |  |  j d 7_ qn  | s| r(| t
 j k r(t  |  _	 |  j!   n  |  j	 r>|  j!   n  d S(   s&   
        Process a key input.
        i    i   N("   Rk   t   modR   t   modst   shiftRl   t   lshiftt   rshiftR   R   R{   t   _non_insertable_keysR   R   R   t   leftR   t   ctrlR   R  t   homeR   R   R.   t   deleteR   t	   backspaceR   t   _non_printable_keyst   chrR   R   RH   R   (   R   R`   Rk   R  t   shift_is_downt   shift_clickedt   unicode(    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRo   F  sD    		.	
			c         C   s   d  S(   N(    (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRg   r  s    c         C   s   d  S(   N(    (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRe   s  s    c         C   s   d  S(   N(    (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRp   t  s    c         C   s   |  j  | j  |  _ d S(   sT   
        Update the position of the text cursor when the mouse is released.
        N(   R   R   R   (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRa   v  s    c         C   s   |  j  s: t j j   t j @r\ |  j |  _ t |  _  q\ n" t j j   t j @s\ t |  _  n  |  j	 | j
  |  _ |  j r d |  _ t |  _ n  |  j   |  j   d S(   s~   
        Handle mouse being pressed: start or stop selecting text, update the
        text cursor, and halt blinking.
        Rd   N(   R   t   pygameRk   t   get_modst
   KMOD_SHIFTR   R   R   RH   R   R   R   R.   R   R   (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRb   |  s    			
c         C   si   | j  \ } } } | re |  j s9 t |  _ |  j |  _ n  |  j | j  |  _ |  j   |  j   n  d S(   s7   
        Handle the text cursor being dragged.
        N(	   Ry   R   R   R   R   R   R   R   R   (   R   R`   R	  t   centerR   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRh     s    		
c         C   s_   t  |  _ |  j |  j _ |  j r6 t  |  _ d |  _ n	 t |  _ t	 |  j
  |  _ |  j   d S(   s5   
        Handle this widget receiving focus.
        i    N(   R   Rf   R   R~   R&   R   R   R   RH   R   R   R   R   (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRi     s    				c         C   s4   |  j  |  j _ t |  _ t |  j _ |  j |  _ d S(   s2   
        Handle this widget losing focus.
        N(	   R   R~   R&   RH   Rf   R   R   R   R   (   R   R`   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyRj     s    	N(   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   s   \R   R   R   R   R   (   s   	Rd   (N   R   R   R   R   R   R
   R   R   RI   R   R   R   R   R   R1   R   R   R   R   R9   R:   R=   R>   RC   RF   RK   RD   R.   R   R   R8   R   R   R   R   Rl   RO   RP   R	  R   R  R   t   pageupt   pagedownt   numlockt   capslockt	   scrollockt   rctrlR  R  t   lctrlt   rmetat   raltt   laltt   lmetat   lsupert   rsupert   modeR  R   R  R   R   RH   R   R   R   R  R   Ro   Rg   Re   Rp   Ra   Rb   Rh   Ri   Rj   (    (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR{     s~   6																						    


	
	,							t   _WidgetWrapperc           B   s)   e  Z d  Z d   Z d   Z d   Z RS(   i    c         O   s.   t  j d 7_ | |  _ | |  _ | |  _ d  S(   Ni   (   R%  t   creation_countert   clst   argst   kwargs(   R   R'  R(  R)  (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR
     s    		c         C   s   |  j  | | |  j |  j  S(   N(   R'  R(  R)  (   R   R   R   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   __call__  s    c         C   s8   | d k r t  d   n t t |   j | |  d  S(   NR'  R(  R)  s   Can't set properties in the class definition of a Widget! Set outside of the declarative region. See http://platipy.org/en/latest/spyral_docs.html#spyral.Form(   s   clss   argss   kwargs(   t   AttributeErrort   superR%  t   __setattr__(   R   t   itemR.   (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR-    s    (   R   R   R&  R
   R*  R-  (    (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR%    s   		t   modulec           B   s   e  Z d    Z RS(   c         C   s    t  |  | t j t |   d  S(   N(   t   setattrt	   functoolst   partialR%  (   R   R   R'  (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR     s    (   R   R   R   (    (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyR/    s   t	   TextInputt   RadioButtont   Checkboxt   ToggleButtonRq   (   R   t   typest   sysR1  R   R   R  t   bisectR    R	   R   R   RM   Rs   Rt   Ru   t   objectRx   R{   t   modulesR   t   oldR%  t
   ModuleTypeR/  t   widgetst   __dict__t   updateR   (    (    (    s2   /usr/lib/python2.7/site-packages/spyral/widgets.pyt   <module>   s8   
  0