
    ;OOf                        d dl mZmZ d dlmZ d dlmZmZmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZmZmZ d dlmZ d dlmZmZ d dlmZmZmZmZ  G d de      Z G d	 d
 ed      e      Z  G d de      Z! G d d ed      e      Z" G d de"      Z# G d de$      Z% G d de      Z& G d de$      Z' G d de      Z( G d de$      Z) G d de      Z* G d de      Z+d  Z,d! Z-d" Z.d# Z/d$ Z0d% Z1d& Z2d' Z3d( Z4d) Z5d* Z6e7d+k(  r e6        y,y,)-    )divisionprint_function)	int_scale)WidgetWidgetErrorBOXFLOWLEFTCENTERRIGHTPACKCLIPGIVENRELATIVERELATIVE_100TOPMIDDLEBOTTOMdelegate_to_widget_mixin)remove_defaults)CompositeCanvasSolidCanvas)DividerEditText	SolidFillc                   \    e Zd ZdZd Zd Zd Zd Z eee      Z	d Z
 ee
      Zd Zd Zy	)
WidgetDecorationa  
    original_widget -- the widget being decorated

    This is a base class for decoration widgets, widgets
    that contain one or more widgets and only ever have
    a single focus.  This type of widget will affect the
    display or behaviour of the original_widget but it is
    not part of determining a chain of focus.

    Don't actually do this -- use a WidgetDecoration subclass
    instead, these are not real widgets:

    >>> WidgetDecoration(Text(u"hi"))
    <WidgetDecoration flow widget <Text flow widget 'hi'>>
    c                     || _         y N_original_widgetselforiginal_widgets     Q/var/www/premiumrankchecker/venv/lib/python3.12/site-packages/urwid/decoration.py__init__zWidgetDecoration.__init__1   s
     /    c                 d    | j                   j                         t        | j                        gz   S r    )_WidgetDecoration__super_repr_wordsreprr"   r$   s    r&   r+   zWidgetDecoration._repr_words3   s(    ||'')T$2G2G-H,IIIr(   c                     | j                   S r    r!   r-   s    r&   _get_original_widgetz%WidgetDecoration._get_original_widget6   s    $$$r(   c                 2    || _         | j                          y r    )r"   _invalidater#   s     r&   _set_original_widgetz%WidgetDecoration._set_original_widget8   s     /r(   c                 T    | }t        |d      r|j                  }t        |d      r|S )a  
        Return the widget without decorations.  If there is only one
        Decoration then this is the same as original_widget.

        >>> t = Text('hello')
        >>> wd1 = WidgetDecoration(t)
        >>> wd2 = WidgetDecoration(wd1)
        >>> wd3 = WidgetDecoration(wd2)
        >>> wd3.original_widget is wd2
        True
        >>> wd3.base_widget is t
        True
        r"   )hasattrr"   )r$   ws     r&   _get_base_widgetz!WidgetDecoration._get_base_widget=   s1     a+,""A a+,r(   c                 6    | j                   j                         S r    r"   
selectabler-   s    r&   r9   zWidgetDecoration.selectableR   s    $$//11r(   c                 6    | j                   j                         S r    r"   sizingr-   s    r&   r<   zWidgetDecoration.sizingU       $$++--r(   N)__name__
__module____qualname____doc__r'   r+   r/   r2   propertyr%   r6   base_widgetr9   r<    r(   r&   r   r   !   sH    0J% 35IJO& +,K2.r(   r   c                       e Zd ZdZy)WidgetPlaceholdera  
    This is a do-nothing decoration widget that can be used for swapping
    between widgets without modifying the container of this widget.

    This can be useful for making an interface with a number of distinct
    pages or for showing and hiding menu or status bars.

    The widget displayed is stored as the self.original_widget property and
    can be changed by assigning a new widget to it.
    N)r>   r?   r@   rA   rD   r(   r&   rF   rF   Y   s    	 	r(   rF   r"   c                       e Zd Zy)AttrMapErrorNr>   r?   r@   rD   r(   r&   rH   rH   h       r(   rH   c                   b    e Zd ZdZd
dZd Zd Zd Z eee      Z	d Z
d Z ee
e      Zdd	Zy)AttrMapz
    AttrMap is a decoration that maps one set of attributes to another.
    This object will pass all function calls and variable references to the
    wrapped widget.
    Nc                    | j                   j                  |       t        |      t        k7  r| j	                  d|i       n| j	                  |       |&t        |      t        k7  r| j                  d|i       y| j                  |       y)a  
        :param w: widget to wrap (stored as self.original_widget)
        :type w: widget

        :param attr_map: attribute to apply to *w*, or dict of old display
            attribute: new display attribute mappings
        :type attr_map: display attribute or dict

        :param focus_map: attribute to apply when in focus or dict of
            old display attribute: new display attribute mappings;
            if ``None`` use *attr*
        :type focus_map: display attribute or dict

        >>> AttrMap(Divider(u"!"), 'bright')
        <AttrMap flow widget <Divider flow widget '!'> attr_map={None: 'bright'}>
        >>> AttrMap(Edit(), 'notfocus', 'focus')
        <AttrMap selectable flow widget <Edit selectable flow widget '' edit_pos=0> attr_map={None: 'notfocus'} focus_map={None: 'focus'}>
        >>> size = (5,)
        >>> am = AttrMap(Text(u"hi"), 'greeting', 'fgreet')
        >>> next(am.render(size, focus=False).content()) # ... = b in Python 3
        [('greeting', None, ...'hi   ')]
        >>> next(am.render(size, focus=True).content())
        [('fgreet', None, ...'hi   ')]
        >>> am2 = AttrMap(Text(('word', u"hi")), {'word':'greeting', None:'bg'})
        >>> am2
        <AttrMap flow widget <Text flow widget 'hi'> attr_map={'word': 'greeting', None: 'bg'}>
        >>> next(am2.render(size).content())
        [('greeting', None, ...'hi'), ('bg', None, ...'   ')]
        N)_AttrMap__superr'   typedictset_attr_mapset_focus_map)r$   r5   attr_map	focus_maps       r&   r'   zAttrMap.__init__q   su    < 	a >T!tX./h' T)_%<i01y)r(   c                     t        | j                  j                         | j                        }| j                  | j                  |d<   |S )NrS   rT   )rP   rN   _repr_attrs	_attr_map
_focus_mapr$   ds     r&   rW   zAttrMap._repr_attrs   s;    ))+dnnE??&!__AkNr(   c                 ,    t        | j                        S r    )rP   rX   r-   s    r&   get_attr_mapzAttrMap.get_attr_map   s     DNN##r(   c                     |j                         D ].  \  }}|j                  r|j                  rt        |d|d       || _        | j	                          y)a  
        Set the attribute mapping dictionary {from_attr: to_attr, ...}

        Note this function does not accept a single attribute the way the
        constructor does.  You must specify {None: attribute} instead.

        >>> w = AttrMap(Text(u"hi"), None)
        >>> w.set_attr_map({'a':'b'})
        >>> w
        <AttrMap flow widget <Text flow widget 'hi'> attr_map={'a': 'b'}>
        :; attribute mapping is invalid.  Attributes must be hashableN)items__hash__rH   rX   r1   )r$   rS   	from_attrto_attrs       r&   rQ   zAttrMap.set_attr_map   sa     #+.."2 	JIw%%W-=-="5>$I J J	J "r(   c                 F    | j                   rt        | j                         S y r    )rY   rP   r-   s    r&   get_focus_mapzAttrMap.get_focus_map   s     ??(( r(   c                     |A|j                         D ].  \  }}|j                  r|j                  rt        |d|d       || _        | j	                          y)az  
        Set the focus attribute mapping dictionary
        {from_attr: to_attr, ...}

        If None this widget will use the attr mapping instead (no change
        when in focus).

        Note this function does not accept a single attribute the way the
        constructor does.  You must specify {None: attribute} instead.

        >>> w = AttrMap(Text(u"hi"), {})
        >>> w.set_focus_map({'a':'b'})
        >>> w
        <AttrMap flow widget <Text flow widget 'hi'> attr_map={} focus_map={'a': 'b'}>
        >>> w.set_focus_map(None)
        >>> w
        <AttrMap flow widget <Text flow widget 'hi'> attr_map={}>
        Nr_   r`   )ra   rb   rH   rY   r1   )r$   rT   rc   rd   s       r&   rR   zAttrMap.set_focus_map   sg    &  &/oo&7 N"	7 ))1A1A&9BG(M N NN $r(   c                     | j                   }|r| j                  | j                  }| j                  j                  ||      }t	        |      }|j                  |       |S )zK
        Render wrapped widget and apply attribute. Return canvas.
        focus)rX   rY   r"   renderr   fill_attr_apply)r$   sizerj   rS   canvs        r&   rk   zAttrMap.render   sZ     >>T__0H$$++D+>t$X&r(   r    F)r>   r?   r@   rA   r'   rW   r]   rQ   rB   rS   rf   rR   rT   rk   rD   r(   r&   rL   rL   k   sG    
(*T$$ l3H)
4 6I
r(   rL   c                       e Zd Zd
dZd Zej                  Zej                  Z	 e
ee	      Zd Zd Z e
ee      Zd Zd Z e
ee      Zd Zd	 Zy)AttrWrapNc                 >    | j                   j                  |||       y)a  
        w -- widget to wrap (stored as self.original_widget)
        attr -- attribute to apply to w
        focus_attr -- attribute to apply when in focus, if None use attr

        This widget is a special case of the new AttrMap widget, and it
        will pass all function calls and variable references to the wrapped
        widget.  This class is maintained for backwards compatibility only,
        new code should use AttrMap instead.

        >>> AttrWrap(Divider(u"!"), 'bright')
        <AttrWrap flow widget <Divider flow widget '!'> attr='bright'>
        >>> AttrWrap(Edit(), 'notfocus', 'focus')
        <AttrWrap selectable flow widget <Edit selectable flow widget '' edit_pos=0> attr='notfocus' focus_attr='focus'>
        >>> size = (5,)
        >>> aw = AttrWrap(Text(u"hi"), 'greeting', 'fgreet')
        >>> next(aw.render(size, focus=False).content())
        [('greeting', None, ...'hi   ')]
        >>> next(aw.render(size, focus=True).content())
        [('fgreet', None, ...'hi   ')]
        N)_AttrWrap__superr'   )r$   r5   attr
focus_attrs       r&   r'   zAttrWrap.__init__   s    , 	az2r(   c                     t        | j                  j                         | j                        }|d= d|v r|d= | j                  | j                  |d<   |S )N)rt   rS   rT   ru   )rP   rs   rW   rt   ru   rZ   s     r&   rW   zAttrWrap._repr_attrs  sQ    ))+$))<jM!+??&"ooAlOr(   c                      | j                   d    S r    rV   r-   s    r&   get_attrzAttrWrap.get_attr  s    }}T""r(   c                 *    | j                  d|i       y)z
        Set the attribute to apply to the wrapped widget

        >> w = AttrWrap(Divider("-"), None)
        >> w.set_attr('new_attr')
        >> w
        <AttrWrap flow widget <Divider flow widget '-'> attr='new_attr'>
        N)rQ   )r$   rt   s     r&   set_attrzAttrWrap.set_attr  s     	4,'r(   c                 *    | j                   }|r|d    S y r    )rT   )r$   rT   s     r&   get_focus_attrzAttrWrap.get_focus_attr  s    NN	T?" r(   c                 *    | j                  d|i       y)a  
        Set the attribute to apply to the wapped widget when it is in
        focus

        If None this widget will use the attr instead (no change when in
        focus).

        >> w = AttrWrap(Divider("-"), 'old')
        >> w.set_focus_attr('new_attr')
        >> w
        <AttrWrap flow widget <Divider flow widget '-'> attr='old' focus_attr='new_attr'>
        >> w.set_focus_attr(None)
        >> w
        <AttrWrap flow widget <Divider flow widget '-'> attr='old'>
        N)rR   )r$   ru   s     r&   set_focus_attrzAttrWrap.set_focus_attr#  s      	D*-.r(   c                 .    t        | j                  |      S )z
        Call getattr on wrapped widget.  This has been the longstanding
        behaviour of AttrWrap, but is discouraged.  New code should be
        using AttrMap and .base_widget or .original_widget instead.
        )getattrr"   r$   names     r&   __getattr__zAttrWrap.__getattr__6  s     t,,d33r(   c                 6    | j                   j                         S r    r;   r-   s    r&   r<   zAttrWrap.sizing?  r=   r(   r    )r>   r?   r@   r'   rW   r   r/   get_wr2   set_wrB   r5   rx   rz   rt   r|   r~   ru   r   r<   rD   r(   r&   rq   rq      sj    30 11E11EA#	( Hh'D#/" ..9J4.r(   rq   c                       e Zd Zy)BoxAdapterErrorNrI   rD   r(   r&   r   r   C  rJ   r(   r   c                       e Zd ZdZdgZd Zd Z eej                  ej                        Zd ZddZd Zd Zd	 Zd
 Zd ZddZd Zy)
BoxAdapterzM
    Adapter for using a box widget where a flow widget would usually go
    rowsc                     t        |d      r$t        |j                         vrt        d|z        t        j                  | |       || _        y)aa  
        Create a flow widget that contains a box widget

        :param box_widget: box widget to wrap
        :type box_widget: Widget
        :param height: number of rows for box widget
        :type height: int

        >>> BoxAdapter(SolidFill(u"x"), 5) # 5-rows of x's
        <BoxAdapter flow widget <SolidFill box widget 'x'> height=5>
        r<   z%r is not a box widgetN)r4   r   r<   r   r   r'   height)r$   
box_widgetr   s      r&   r'   zBoxAdapter.__init__L  sM     :x(S
8I8I8K-K!":#  !!$z2r(   c                 `    t        | j                  j                         | j                        S )Nr   )rP   _BoxAdapter__superrW   r   r-   s    r&   rW   zBoxAdapter._repr_attrs_  s     DLL,,.t{{CCr(   c                 "    t        t        g      S r    )setr	   r-   s    r&   r<   zBoxAdapter.sizingf  s    D6{r(   c                     | j                   S )z
        Return the predetermined height (behave like a flow widget)

        >>> BoxAdapter(SolidFill(u"x"), 5).rows((20,))
        5
        r   r$   rm   rj   s      r&   r   zBoxAdapter.rowsi  s     {{r(   c                     |\  }t        | j                  d      sy | j                  j                  || j                  f      S )Nget_cursor_coords)r4   r"   r   r   r$   rm   maxcols      r&   r   zBoxAdapter.get_cursor_coordst  s=    	t,,-@A$$667LMMr(   c                     |\  }t        | j                  d      sy | j                  j                  || j                  f      S )Nget_pref_col)r4   r"   r   r   r   s      r&   r   zBoxAdapter.get_pref_colz  s<    	t,,^<$$1164;;2GHHr(   c                 Z    |\  }| j                   j                  || j                  f|      S r    )r"   keypressr   )r$   rm   keyr   s       r&   r   zBoxAdapter.keypress  s+    	$$--vt{{.CSIIr(   c                     |\  }t        | j                  d      sy| j                  j                  || j                  f||      S )Nmove_cursor_to_coordsT)r4   r"   r   r   )r$   rm   colrowr   s        r&   r   z BoxAdapter.move_cursor_to_coords  sI    	t,,-DE$$::FKK<s% 	%r(   c                     |\  }t        | j                  d      sy| j                  j                  || j                  f|||||      S )Nmouse_eventF)r4   r"   r   r   )r$   rm   eventbuttonr   r   rj   r   s           r&   r   zBoxAdapter.mouse_event  sK    	t,,];$$00&$++1F63U, 	,r(   c                 t    |\  }| j                   j                  || j                  f|      }t        |      }|S r    )r"   rk   r   r   )r$   rm   rj   r   rn   s        r&   rk   zBoxAdapter.render  s9    	$$++VT[[,A5It$r(   c                 .    t        | j                  |      S )z+
        Pass calls to box widget.
        )r   r   r   s     r&   r   zBoxAdapter.__getattr__  s     t--r(   Nro   )r>   r?   r@   rA   no_cacher'   rW   rB   r   r/   r2   r   r<   r   r   r   r   r   r   rk   r   rD   r(   r&   r   r   F  si     xH&D *??--/JNIJ%,.r(   r   c                       e Zd Zy)PaddingErrorNrI   rD   r(   r&   r   r     rJ   r(   r   c                       e Zd ZeedddfdZd Zd Zd Zd Z	 e
ee	      Zd Zd	 Z e
ee      Zdd
Zd ZddZd Zd Zd Zd Zd Zy)PaddingNr   c                    | j                   j                  |       t        |      t        k(  r&|d   dv r|d   dk(  r|d   }t        }n|d   }t
        }t        |      t        k(  r |d   dv r|d   dk(  r|d   }n|d   }t        }|t        }|| _        || _	        t        |t              \  | _        | _        t        |t              \  | _        | _        || _        y)a  
        :param w: a box, flow or fixed widget to pad on the left and/or right
            this widget is stored as self.original_widget
        :type w: Widget

        :param align: one of: ``'left'``, ``'center'``, ``'right'``
            (``'relative'``, *percentage* 0=left 100=right)

        :param width: one of:

            *given width*
              integer number of columns for self.original_widget

            ``'pack'``
              try to pack self.original_widget to its ideal size

            (``'relative'``, *percentage of total width*)
              make width depend on the container's width

            ``'clip'``
              to enable clipping mode for a fixed widget

        :param min_width: the minimum number of columns for
            self.original_widget or ``None``
        :type min_width: int

        :param left: a fixed number of columns to pad on the left
        :type left: int

        :param right: a fixed number of columns to pad on the right
        :type right: int

        Clipping Mode: (width= ``'clip'``)
        In clipping mode this padding widget will behave as a flow
        widget and self.original_widget will be treated as a fixed
        widget.  self.original_widget will will be clipped to fit
        the available number of columns.  For example if align is
        ``'left'`` then self.original_widget may be clipped on the right.

        >>> size = (7,)
        >>> def pr(w):
        ...     for t in w.render(size).text:
        ...         print("|%s|" % (t.decode('ascii'),))
        >>> pr(Padding(Text(u"Head"), ('relative', 20), 'pack'))
        | Head  |
        >>> pr(Padding(Divider(u"-"), left=2, right=1))
        |  ---- |
        >>> pr(Padding(Divider(u"*"), 'center', 3))
        |  ***  |
        >>> p=Padding(Text(u"1234"), 'left', 2, None, 1, 1)
        >>> p
        <Padding flow widget <Text flow widget '1234'> left=1 right=1 width=2>
        >>> pr(p)   # align against left
        | 12    |
        | 34    |
        >>> p.align = 'right'
        >>> pr(p)   # align against right
        |    12 |
        |    34 |
        >>> pr(Padding(Text(u"hi\nthere"), 'right', 'pack')) # pack text first
        |  hi   |
        |  there|
        r   )
fixed leftzfixed rightr      N)_Padding__superr'   rO   tupler
   r   r   r   leftrightnormalize_alignr   _align_type_align_amountnormalize_width_width_type_width_amount	min_width)r$   r5   alignwidthr   r   r   s          r&   r'   zPadding.__init__  s    B 	a  ;%E!H 1 %Qx%Qxa;%E!H 1 %Qx%Qxa E =E	
/>u0,$,/>u0,$,"r(   c                 |    | j                   t        k(  rt        t        g      S | j                  j                         S r    )r   r   r   r	   r%   r<   r-   s    r&   r<   zPadding.sizing  s1    t#v;##**,,r(   c                     t        | j                  j                         | j                  | j                  | j
                  | j                  | j                        }t        |t        j                        S )N)r   r   r   r   r   )rP   r   rW   r   r   r   r   r   r   r   r'   r$   attrss     r&   rW   zPadding._repr_attrs	  sS    T\\--/******nn& ug&6&677r(   c                 B    t        | j                  | j                        S )z7
        Return the padding alignment setting.
        )simplify_alignr   r   r-   s    r&   
_get_alignzPadding._get_align       d..0B0BCCr(   c                 ^    t        |t              \  | _        | _        | j	                          y)z,
        Set the padding alignment.
        N)r   r   r   r   r1   )r$   r   s     r&   
_set_alignzPadding._set_align  *     0?u0,$,r(   c                 B    t        | j                  | j                        S )z+
        Return the padding width.
        )simplify_widthr   r   r-   s    r&   
_get_widthzPadding._get_width   r   r(   c                 ^    t        |t              \  | _        | _        | j	                          y)z(
        Set the padding width.
        N)r   r   r   r   r1   )r$   r   s     r&   
_set_widthzPadding._set_width%  r   r(   c                 *   | j                  ||      \  }}|d   }|||z   z  }| j                  t        k(  r| j                  j	                  d|      }n#| j                  j	                  |f|dd  z   |      }|j                         dk(  rGt        d|d   |j                               }t        |      }|j                  | j                  g       |S t        |      }|j                  | j                  g       |dk7  s|dk7  r|j                  ||       |S )Nr   rD   r    )padding_valuesr   r   r"   rk   colsr   r   r   set_dependspad_trim_left_right)r$   rm   rj   r   r   r   rn   s          r&   rk   zPadding.render.  s	   ))$6ea$u*t#((//E:D((//	$qr(0BEJD99;!sDGTYY[9D"4(Dd3345Kt$$//0119
$$T51r(   c           
         |d   }| j                   t        k(  r^| j                  j                  d|      \  }}t	        || j
                  | j                  t        |d| j                  | j                        S | j                   t        k(  rt        || j                  z
  | j                  z
  | j                  xs d      }| j                  j                  |f|      \  }}t	        || j
                  | j                  t        || j                  | j                  | j                        S t	        || j
                  | j                  | j                   | j                  | j                  | j                  | j                        S )z|Return the number of columns to pad on the left and right.

        Override this method to define custom padding behaviour.r   rD   ri   N)r   r   r"   packcalculate_left_right_paddingr   r   r   r   r   maxr   r   r   )r$   rm   rj   r   r   ignoremaxwidths          r&   r   zPadding.padding_valuesD  sK    at# 1166r6GME6/  $"4"4eT499djj: : t#6DII-

:#!%H"3388( 9 OUF/  $"4"4udnn		4::' ' ,Fd00d00NNDIItzz3 	3r(   c                 Z   |\  }| j                  ||      \  }}| j                  t        k(  r(| j                  j	                  ||z
  |z
  f|      \  }}|S | j                  t
        k(  r!| j                  j	                  d|      \  }}	|	S | j                  j                  ||z
  |z
  f|      S )z0Return the rows needed for self.original_widget.rD   ri   )r   r   r   r"   r   r   r   )
r$   rm   rj   r   r   r   pcolsprowsfcolsfrowss
             r&   r   zPadding.rows\  s    	))$6et#0055vd{57H6JLE5Lt#0055b%@LE5L$$))6$;u+<*>e)LLr(   c                     |d   }| j                  |d      \  }}||z
  |z
  f|dd z   }| j                  j                  ||      S )z'Pass keypress to self._original_widget.r   Tr   N)r   r"   r   )r$   rm   r   r   r   r   maxvalss          r&   r   zPadding.keypressi  sV    a))$5e$;u$&tABx/$$--gs;;r(   c                     t        | j                  d      sy| j                  |d      \  }}|d   }||z
  |z
  f|dd z   }|d   dk(  ry| j                  j                  |      }|y|\  }}||z   |fS )zDReturn the (x,y) coordinates of cursor within self._original_widget.r   NTr   r   )r4   r"   r   r   )	r$   rm   r   r   r   r   coordsxys	            r&   r   zPadding.get_cursor_coordsp  s    t,,-@A))$5ea$;u$&tABx/1:?&&88A>1vqyr(   c                    t        | j                  d      sy| j                  |d      \  }}|d   }||z
  |z
  f|dd z   }t        |      t        k(  r||k  r|}n|||z
  k\  r||z
  dz
  }||z  }| j                  j                  |||      S )zSet the cursor position with (x,y) coordinates of self._original_widget.

        Returns True if move succeeded, False otherwise.
        r   Tr   r   N)r4   r"   r   rO   intr   )r$   rm   r   r   r   r   r   r   s           r&   r   zPadding.move_cursor_to_coords  s    
 t,,-DE))$5ea$;u$&tABx/7C<4xfUl"5LNIA$$::7AqIIr(   c                     t        | j                  d      sy| j                  ||      \  }}|d   }	||k  s||	|z
  k\  ry|	|z
  |z
  f|dd z   }
| j                  j                  |
||||z
  ||      S )z=Send mouse event if position is within self._original_widget.r   Fr   r   N)r4   r"   r   r   )r$   rm   r   r   r   r   rj   r   r   r   r   s              r&   r   zPadding.mouse_event  s    t,,];))$6eat8qF5L($;u$&tABx/$$00%4QR 	r(   c                     t        | j                  d      sy| j                  |d      \  }}|d   }||z
  |z
  f|dd z   }| j                  j                  |      }t	        |      t
        k(  r||z   S |S )z@Return the preferred column from self._original_widget, or None.r   NTr   r   )r4   r"   r   r   rO   r   )r$   rm   r   r   r   r   r   s          r&   r   zPadding.get_pref_col  s    t,,^<))$5ea$;u$&tABx/!!..w77c>T6Mr(   ro   )r>   r?   r@   r
   r   r'   r<   rW   r   r   rB   r   r   r   r   rk   r   r   r   r   r   r   r   rD   r(   r&   r   r     s{     $LD!^#@-
8D
 Z,ED
 Z,E,30M<J$

r(   r   c                       e Zd Zy)FillerErrorNrI   rD   r(   r&   r   r     rJ   r(   r   c                       e Zd ZeedddfdZd Zd Zej                  Z
ej                  Z ee
e      Zd Zd ZddZd	 Zd
 Zd Zd Zd Zy)FillerNr   c                    | j                   j                  |       t        |t              rm|d   dk(  r/t        |t              r|d   dk7  rt	        d      |d   }t
        }n6|d   dk(  r.t        |t              r|d   dk7  rt	        d      |d   }t
        }t        |t              r'|d   dk(  r|d   }t        }n|d   dk(  r|d   }t        }|	|t        k(  rt        }|| _
        || _        t        |t              \  | _        | _        t        |t              \  | _        | _        | j                   t$        t        fvr|| _        yd| _        y)a  
        :param body: a flow widget or box widget to be filled around (stored
            as self.original_widget)
        :type body: Widget

        :param valign: one of:
            ``'top'``, ``'middle'``, ``'bottom'``,
            (``'relative'``, *percentage* 0=top 100=bottom)

        :param height: one of:

            ``'pack'``
              if body is a flow widget

            *given height*
              integer number of rows for self.original_widget

            (``'relative'``, *percentage of total height*)
              make height depend on container's height

        :param min_height: one of:

            ``None``
              if no minimum or if body is a flow widget

            *minimum height*
              integer number of rows for the widget when height not fixed

        :param top: a fixed number of rows to fill at the top
        :type top: int
        :param bottom: a fixed number of rows to fill at the bottom
        :type bottom: int

        If body is a flow widget then height must be ``'flow'`` and
        *min_height* will be ignored.

        Filler widgets will try to satisfy height argument first by
        reducing the valign amount when necessary.  If height still
        cannot be satisfied it will also be reduced.
        r   z	fixed topzfixed bottomz:fixed top height may only be used with fixed bottom valignr   z:fixed bottom height may only be used with fixed top valignN)_Filler__superr'   
isinstancer   r   r   r   r   r	   r   topbottomnormalize_valignvalign_typevalign_amountnormalize_heightheight_typeheight_amountr   
min_height)r$   bodyvalignr   r   r   r   s          r&   r'   zFiller.__init__  sY   T 	d# fe$ayK'!&%0F1I4O% '3 4 4Qi%n,!&%0F1I4L% '0 1 1%fe$ayK'Qin, >Vt^F/?0,$,/?0,$, E4=0(DO"DOr(   c                 "    t        t        g      S r    )r   r   r-   s    r&   r<   zFiller.sizing  s    C5zr(   c                 <   t        | j                  j                         t        | j                  | j
                        t        | j                  | j                        | j                  | j                  | j                        }t        |t        j                        S )N)r   r   r   r   r   )rP   r   rW   simplify_valignr   r   simplify_heightr   r   r   r   r   r   r   r'   r   s     r&   rW   zFiller._repr_attrs  so    T\\--/"4#3#3T5G5GH"4#3#3T5G5GH;;( ufoo66r(   c                 6    | j                   j                         S )zReturn selectable from body.r8   r-   s    r&   r9   zFiller.selectable  s    $$//11r(   c           
         |\  }}| j                   t        k(  r\| j                  j                  |f|      }t	        || j
                  | j                  t        |d| j                  | j                        S t	        || j
                  | j                  | j                   | j                  | j                  | j                  | j                        S )z
        Return the number of rows to pad on the top and bottom.

        Override this method to define custom padding behaviour.
        ri   N)r   r   r"   r   calculate_top_bottom_fillerr   r   r   r   r   r   r   )r$   rm   rj   r   maxrowr   s         r&   filler_valueszFiller.filler_values  s      t#**//	/FF.v  $"4"4vdhh- -
 +6d00d00OOTXXt{{4 	4r(   c                    |\  }}| j                  ||      \  }}| j                  t        k(  r| j                  j	                  |f|      }n$| j                  j	                  |||z
  |z
  f|      }t        |      }|rQ|j                         |kD  r>|j                  2|j                  \  }}	|	|k\  r|j                  |	|z
  dz   ||z
  |z
         |j                         |kD  r|j                  d|       |S |j                  ||       |S )z:Render self.original_widget with space above and/or below.r   r   )
r  r   r   r"   rk   r   r   cursortrimpad_trim_top_bottom)
r$   rm   rj   r   r  r   r   rn   cxcys
             r&   rk   zFiller.render+  s    ((u5Vt#((//	5AD((//s
68I0J5QDt$diikF*t{{/F[[FBV|		"V)A+fSj&7899;IIa K  f-r(   c                     |\  }}| j                   t        k(  r| j                  j                  |f|      S | j	                  ||fd      \  }}| j                  j                  |||z
  |z
  f|      S )z&Pass keypress to self.original_widget.T)r   r   r"   r   r  )r$   rm   r   r   r  r   r   s          r&   r   zFiller.keypressA  sv    t#((116)SAA((&$?V$$--vfSj6G.H#NNr(   c                 <   |\  }}t        | j                  d      sy| j                  |d      \  }}| j                  t        k(  r| j                  j                  |f      }n#| j                  j                  |||z
  |z
  f      }|sy|\  }}||k\  r|dz
  }|||z   fS )z6Return cursor coords from self.original_widget if any.r   NTr   )r4   r"   r  r   r   r   )	r$   rm   r   r  r   r   r   r   r   s	            r&   r   zFiller.get_cursor_coordsJ  s    t,,.AB((t4Vt#**<<fYGF**<<s
6)*,F1;qA!C%xr(   c                    |\  }}t        | j                  d      sy| j                  t        k(  r| j                  j	                  |f      }|S | j                  |d      \  }}| j                  j	                  |||z
  |z
  f      }|S )z1Return pref_col from self.original_widget if any.r   NT)r4   r"   r   r   r   r  )r$   rm   r   r  r   r   r   s          r&   r   zFiller.get_pref_col]  s    t,,n=t#%%22F9=A 	 ,,T48KC%%22F*+-A r(   c                 8   |\  }}t        | j                  d      sy| j                  |d      \  }}||k  s|||z
  k\  ry| j                  t        k(  r!| j                  j                  |f|||z
        S | j                  j                  |||z
  |z
  f|||z
        S )Pass to self.original_widget.r   TF)r4   r"   r  r   r   r   )r$   rm   r   r   r   r  r   r   s           r&   r   zFiller.move_cursor_to_coordsl  s    t,,.EF((t4V9vf},t#((>>ySW $$::VCZ&'c#g7 	7r(   c                 D   |\  }}t        | j                  d      sy| j                  |d      \  }	}
||	k  s|||
z
  k\  ry| j                  t        k(  r$| j                  j                  |f|||||	z
  |      S | j                  j                  |||	z
  |
z
  f|||||	z
  |      S )r  r   FT)r4   r"   r  r   r   r   )r$   rm   r   r   r   r   rj   r   r  r   r   s              r&   r   zFiller.mouse_event|  s    t,,m<((t4V9vf},t#((44fYvsCGU4 4$$00&&*V:K1L6#s3w/ 	/r(   ro   )r>   r?   r@   r   r   r'   r<   rW   r   r/   get_bodyr2   set_bodyrB   r   r9   r  rk   r   r   r   r   r   rD   r(   r&   r   r     sl    $*4D!P#d7  44H44HHh'D24*,O&7 /r(   r   c                   >    e Zd ZdZdgZdZd Zd
dZd Zd
dZ	d
dZ
y	)WidgetDisablez
    A decoration widget that disables interaction with the widget it
    wraps.  This widget always passes focus=False to the wrapped widget,
    even if it somehow does become the focus.
    r   Tc                      yNFrD   r-   s    r&   r9   zWidgetDisable.selectable  s    r(   c                 :    | j                   j                  |d      S r  )r"   r   r   s      r&   r   zWidgetDisable.rows      $$))$66r(   c                 6    | j                   j                         S r    r;   r-   s    r&   r<   zWidgetDisable.sizing  r=   r(   c                 :    | j                   j                  |d      S r  )r"   r   r   s      r&   r   zWidgetDisable.pack  r  r(   c                 P    | j                   j                  |d      }t        |      S r  )r"   rk   r   )r$   rm   rj   rn   s       r&   rk   zWidgetDisable.render  s%    $$++D%8t$$r(   Nro   )r>   r?   r@   rA   r   ignore_focusr9   r   r<   r   rk   rD   r(   r&   r  r    s.    
 xHL7.7%r(   r  c                     | t         t        t        fv r| dfS t        |       t        k(  rt        |       dk(  r| d   t        k(  r| S  |d| d      )zy
    Split align into (align_type, align_amount).  Raise exception err
    if align doesn't match a valid alignment.
    N   r   zalign value zS is not one of 'left', 'center', 'right', ('relative', percentage 0=left 100=right))r
   r   r   rO   r   lenr   )r   errs     r&   r   r     sX    
 vu%%t}	e	#e*/eAh(6J
  r(   c                      | t         k(  r| |fS | S )zc
    Recombine (align_type, align_amount) into an align value.
    Inverse of normalize_align.
    r   )
align_typealign_amounts     r&   r   r     s    
 XL))r(   c                     | t         t        fv r| dfS t        |       t        k(  rt        | fS t        |       t
        k(  rt        |       dk(  r| d   t        k(  r| S  |d| d      )zy
    Split width into (width_type, width_amount).  Raise exception err
    if width doesn't match a valid alignment.
    Nr  r   zwidth value z_ is not one of fixed number of columns, 'pack', ('relative', percentage of total width), 'clip')r   r   rO   r   r   r   r  r   )r   r  s     r&   r   r     sk    
 tt}	e	u~	e	#e*/eAh(6J
  r(   c                 @    | t         t        fv r| S | t        k(  r|S | |fS )zc
    Recombine (width_type, width_amount) into an width value.
    Inverse of normalize_width.
    )r   r   r   )
width_typewidth_amounts     r&   r   r     s/    
 dD\!	u	%%r(   c                     | t         t        t        fv r| dfS t        | t              rt        |       dk(  r| d   t        k(  r| S  |d| d      )z{
    Split align into (valign_type, valign_amount).  Raise exception err
    if align doesn't match a valid alignment.
    Nr  r   zvalign value zS is not one of 'top', 'middle', 'bottom', ('relative', percentage 0=left 100=right))r   r   r   r   r   r  r   )r   r  s     r&   r   r     sX    
 #vv&&~
VU
#Fq(81I!
  r(   c                      | t         k(  r| |fS | S )zg
    Recombine (valign_type, valign_amount) into an valign value.
    Inverse of normalize_valign.
    r!  )r   r   s     r&   r   r     s    
 h]++r(   c                     | t         t        fv r| dfS t        | t              rt	        |       dk(  r| d   t
        k(  r| S t        | t              rt        | fS  |d| d      )zi
    Split height into (height_type, height_amount).  Raise exception err
    if height isn't valid.
    Nr  r   zheight value zX is not one of fixed number of columns, 'pack', ('relative', percentage of total height))r	   r   r   r   r  r   r   r   )r   r  s     r&   r   r     si    
 $~
VU
#Fq(81I!	FC	 v
  r(   c                 @    | t         t        fv r| S | t        k(  r|S | |fS )zg
    Recombine (height_type, height_amount) into an height value.
    Inverse of normalize_height.
    )r	   r   r   )r   r   s     r&   r   r     s/    
 tTl"		''r(   c                    |t         k(  r1t        | |z
  |z
  d      }t        |d|dz         }	|t        |	|      }	n|}	t        dt        dt
        di}
|
j                  ||      }| |	z
  |z
  |z
  }|t        d|z
  d|dz         z  }| |	z
  |z
  }|dcxk  r|k  rn nt        ||       }||z  }||z  }n%|dcxk  r|k  rn nt        ||       }||z  }||z  }t        |d      }t        |d      }||fS )a  
    Return the amount of filler (or clipping) on the top and
    bottom part of maxrow rows to satisfy the following:

    valign_type -- 'top', 'middle', 'bottom', 'relative'
    valign_amount -- a percentage when align_type=='relative'
    height_type -- 'given', 'relative', 'clip'
    height_amount -- a percentage when width_type=='relative'
        otherwise equal to the height of the widget
    min_height -- a desired minimum width for the widget or None
    top -- a fixed number of rows to fill on the top
    bottom -- a fixed number of rows to fill on the bottom

    >>> ctbf = calculate_top_bottom_filler
    >>> ctbf(15, 'top', 0, 'given', 10, None, 2, 0)
    (2, 3)
    >>> ctbf(15, 'relative', 0, 'given', 10, None, 2, 0)
    (2, 3)
    >>> ctbf(15, 'relative', 100, 'given', 10, None, 2, 0)
    (5, 0)
    >>> ctbf(15, 'middle', 0, 'given', 4, None, 2, 0)
    (6, 5)
    >>> ctbf(15, 'middle', 0, 'given', 18, None, 2, 0)
    (0, 0)
    >>> ctbf(20, 'top', 0, 'relative', 60, None, 0, 0)
    (0, 8)
    >>> ctbf(20, 'relative', 30, 'relative', 60, None, 0, 0)
    (2, 6)
    >>> ctbf(20, 'relative', 30, 'relative', 60, 14, 0, 0)
    (2, 4)
    r   e   r   2   d   )r   r   r   r   r   r   getmin)r  r   r   r   r   r   r   r   	maxheightr   standard_alignmentsr   fillershifts                 r&   r  r    s,   B hv-q1	=#y1}=!,Fq&VC8 $$[-@F f_s"V+F
ifc6A:66F
6/F
"C CC&!u%	q	6	FSD!%u c1+C^F;r(   c                    |t         k(  r1t        | |z
  |z
  d      }t        |d|dz         }	|t        |	|      }	n|}	t        dt        dt
        di}
|
j                  ||      }| |	z
  |z
  |z
  }|t        d|z
  d|dz         z  }| |	z
  |z
  }|dk  r|dkD  rt        ||       }||z  }||z  }n!|dk  r|dkD  rt        ||       }||z  }||z  }|t        k7  r"|dk  s|dk  rt        |d      }t        |d      }||fS )a  
    Return the amount of padding (or clipping) on the left and
    right part of maxcol columns to satisfy the following:

    align_type -- 'left', 'center', 'right', 'relative'
    align_amount -- a percentage when align_type=='relative'
    width_type -- 'fixed', 'relative', 'clip'
    width_amount -- a percentage when width_type=='relative'
        otherwise equal to the width of the widget
    min_width -- a desired minimum width for the widget or None
    left -- a fixed number of columns to pad on the left
    right -- a fixed number of columns to pad on the right

    >>> clrp = calculate_left_right_padding
    >>> clrp(15, 'left', 0, 'given', 10, None, 2, 0)
    (2, 3)
    >>> clrp(15, 'relative', 0, 'given', 10, None, 2, 0)
    (2, 3)
    >>> clrp(15, 'relative', 100, 'given', 10, None, 2, 0)
    (5, 0)
    >>> clrp(15, 'center', 0, 'given', 4, None, 2, 0)
    (6, 5)
    >>> clrp(15, 'left', 0, 'clip', 18, None, 0, 0)
    (0, -3)
    >>> clrp(15, 'right', 0, 'clip', 18, None, 0, -1)
    (-2, -1)
    >>> clrp(15, 'center', 0, 'given', 18, None, 2, 0)
    (0, 0)
    >>> clrp(20, 'left', 0, 'relative', 60, None, 0, 0)
    (0, 8)
    >>> clrp(20, 'relative', 30, 'relative', 60, None, 0, 0)
    (2, 6)
    >>> clrp(20, 'relative', 30, 'relative', 60, 14, 0, 0)
    (2, 4)
    r   r-  r   r.  r/  )	r   r   r   r
   r   r   r0  r1  r   )r   r"  r#  r&  r'  r   r   r   r   r   r3  r   paddingr5  s                 r&   r   r   F  s@   J Xv}u,a0,X\: y)E6"eC8##J=E unt#e+G	YsU{C155EE>E!D qyTAXD5&!	eaiED5! Ttax5194|E1;r(   c                  ,    dd l } | j                          y )Nr   )doctesttestmod)r9  s    r&   _testr;    s    OOr(   __main__N)8
__future__r   r   
urwid.utilr   urwid.widgetr   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   urwid.split_reprr   urwid.canvasr   r   r   r   r   r   r   rF   rH   rL   rq   	Exceptionr   r   r   r   r   r   r  r   r   r   r   r   r   r   r   r  r   r;  r>   rD   r(   r&   <module>rC     s:  , 0  3 3 3 3 3 - 5 7 75.v 5.p	01CD		; 	z&'9:<L z|W.w W.t	i 	V.! V.t	9 	E EP	) 	\/ \/|%$ %*	& 	(?DDP Z	G r(   