grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026a BjŒjs¢ã@sÐddlmZmZddlmZddlmZmZmZm Z m Z m Z m Z m Z mZmZmZmZmZmZmZmZddlmZddlmZmZddlmZmZmZmZGdd„deƒZGd d „d ed ƒeƒZ Gd d „d eƒZ!Gdd„ded ƒeƒZ"Gdd„de"ƒZ#Gdd„de$ƒZ%Gdd„deƒZ&Gdd„de$ƒZ'Gdd„deƒZ(Gdd„de$ƒZ)Gdd„deƒZ*Gdd„deƒZ+d d!„Z,d"d#„Z-d$d%„Z.d&d'„Z/d(d)„Z0d*d+„Z1d,d-„Z2d.d/„Z3d0d1„Z4d2d3„Z5d4d5„Z6e7d6k�rÌe6ƒd7S)8é)Ú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@sZeZdZdZdd„Zdd„Zdd„Zdd „ZeeeƒZ d d „Z ee ƒZ d d „Z dd„Z dS)Ú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")) > cCs ||_dS©N©Ú_original_widget©ÚselfÚoriginal_widget©r#ú6/usr/lib64/python3.9/site-packages/urwid/decoration.pyÚ__init__0szWidgetDecoration.__init__cCs|j ¡t|jƒgSr)Z_WidgetDecoration__superÚ _repr_wordsÚreprr©r!r#r#r$r&2szWidgetDecoration._repr_wordscCs|jSrrr(r#r#r$Ú_get_original_widget5sz%WidgetDecoration._get_original_widgetcCs||_| ¡dSr)rÚ _invalidater r#r#r$Ú_set_original_widget7sz%WidgetDecoration._set_original_widgetcCs|}t|dƒr|j}q|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!Úwr#r#r$Ú_get_base_widget<s z!WidgetDecoration._get_base_widgetcCs |j ¡Sr©rÚ selectabler(r#r#r$r0QszWidgetDecoration.selectablecCs |j ¡Sr©rÚsizingr(r#r#r$r2TszWidgetDecoration.sizingN)Ú__name__Ú __module__Ú __qualname__Ú__doc__r%r&r)r+Úpropertyr"r.Z base_widgetr0r2r#r#r#r$r s rc@seZdZdZdS)Ú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)r3r4r5r6r#r#r#r$r8Xs r8rc@s eZdZdS)Ú AttrMapErrorN©r3r4r5r#r#r#r$r9gsr9c@s`eZdZdZddd„Zdd„Zdd„Zd d „ZeeeƒZ d d „Z d d„Z ee e ƒZ ddd„Z dS)Ú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. NcCsd|j |¡t|ƒtkr(| d|i¡n | |¡|durVt|ƒtkrV| d|i¡n | |¡dS)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') attr_map={None: 'bright'}> >>> AttrMap(Edit(), 'notfocus', 'focus') 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 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!r-Úattr_mapÚ focus_mapr#r#r$r%ps   zAttrMap.__init__cCs,t|j ¡|jd�}|jdur(|j|d<|S)N©rArB)r>r<Ú _repr_attrsÚ _attr_mapÚ _focus_map©r!Údr#r#r$rDšs  zAttrMap._repr_attrscCs t|jƒSr)r>rEr(r#r#r$Ú get_attr_map¡szAttrMap.get_attr_mapcCs@| ¡D]$\}}|jr|jstd||fƒ‚q||_| ¡dS)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 attr_map={'a': 'b'}> ú@%r:%r attribute mapping is invalid. Attributes must be hashableN)ÚitemsÚ__hash__r9rEr*)r!rAÚ from_attrÚto_attrr#r#r$r?¥s  ÿzAttrMap.set_attr_mapcCs|jrt|jƒSdSr)rFr>r(r#r#r$Ú get_focus_map¹szAttrMap.get_focus_mapcCsH|dur6| ¡D]$\}}|jr$|jstd||fƒ‚q||_| ¡dS)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 attr_map={} focus_map={'a': 'b'}> >>> w.set_focus_map(None) >>> w attr_map={}> NrJ)rKrLr9rFr*)r!rBrMrNr#r#r$r@¾s ÿzAttrMap.set_focus_mapFcCs@|j}|r|jdur|j}|jj||d�}t|ƒ}| |¡|S)zK Render wrapped widget and apply attribute. Return canvas. N©Úfocus)rErFrÚrenderrZfill_attr_apply)r!ÚsizerQrAÚcanvr#r#r$rRÚs zAttrMap.render)N)F)r3r4r5r6r%rDrIr?r7rArOr@rBrRr#r#r#r$r;js *  r;c@sxeZdZddd„Zdd„ZejZejZ e ee ƒZ dd„Z dd „Z e e e ƒZd d „Zd d „Ze eeƒZdd„Zdd„ZdS)ÚAttrWrapNcCs|j |||¡dS)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') attr='bright'> >>> AttrWrap(Edit(), 'notfocus', 'focus') 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!r-ÚattrÚ focus_attrr#r#r$r%észAttrWrap.__init__cCs@t|j ¡|jd�}|d=d|vr(|d=|jdur<|j|d<|S)N)rWrArBrX)r>rVrDrWrXrGr#r#r$rDs  zAttrWrap._repr_attrscCs |jdSrrCr(r#r#r$Úget_attrszAttrWrap.get_attrcCs| d|i¡dS)zç Set the attribute to apply to the wrapped widget >> w = AttrWrap(Divider("-"), None) >> w.set_attr('new_attr') >> w attr='new_attr'> N)r?)r!rWr#r#r$Úset_attrs zAttrWrap.set_attrcCs|j}|r|dSdSr)rB)r!rBr#r#r$Úget_focus_attrszAttrWrap.get_focus_attrcCs| d|i¡dS)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 attr='old' focus_attr='new_attr'> >> w.set_focus_attr(None) >> w attr='old'> N)r@)r!rXr#r#r$Úset_focus_attr"szAttrWrap.set_focus_attrcCs 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!Únamer#r#r$Ú __getattr__5szAttrWrap.__getattr__cCs |j ¡Srr1r(r#r#r$r2>szAttrWrap.sizing)N)r3r4r5r%rDrr)Zget_wr+Zset_wr7r-rYrZrWr[r\rXr`r2r#r#r#r$rUès      rUc@s eZdZdS)ÚBoxAdapterErrorNr:r#r#r#r$raBsrac@s€eZdZdZdgZdd„Zdd„Zeej ej ƒZ dd„Z dd d „Z d d „Zdd„Zdd„Zdd„Zdd„Zddd„Zdd„ZdS)Ú BoxAdapterzM Adapter for using a box widget where a flow widget would usually go ÚrowscCs8t|dƒr"t| ¡vr"td|ƒ‚t ||¡||_dS)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 height=5> r2z%r is not a box widgetN)r,rr2rarr%Úheight)r!Ú box_widgetrdr#r#r$r%Ks ÿ zBoxAdapter.__init__cCst|j ¡|jd�S)N©rd)r>Z_BoxAdapter__superrDrdr(r#r#r$rD^szBoxAdapter._repr_attrscCs ttgƒSr)Úsetrr(r#r#r$r2eszBoxAdapter.sizingFcCs|jS)z� Return the predetermined height (behave like a flow widget) >>> BoxAdapter(SolidFill(u"x"), 5).rows((20,)) 5 rf©r!rSrQr#r#r$rchszBoxAdapter.rowscCs(|\}t|jdƒsdS|j ||jf¡S)NÚget_cursor_coords)r,rrird©r!rSÚmaxcolr#r#r$riss zBoxAdapter.get_cursor_coordscCs(|\}t|jdƒsdS|j ||jf¡S)NÚ get_pref_col)r,rrlrdrjr#r#r$rlys zBoxAdapter.get_pref_colcCs|\}|j ||jf|¡Sr)rÚkeypressrd)r!rSÚkeyrkr#r#r$rmszBoxAdapter.keypresscCs,|\}t|jdƒsdS|j ||jf||¡S)NÚmove_cursor_to_coordsT)r,rrord)r!rSÚcolÚrowrkr#r#r$roƒs ÿÿz BoxAdapter.move_cursor_to_coordscCs2|\}t|jdƒsdS|j ||jf|||||¡S)NÚ mouse_eventF)r,rrrrd)r!rSÚeventÚbuttonrprqrQrkr#r#r$rrŠs   ÿzBoxAdapter.mouse_eventcCs&|\}|j ||jf|¡}t|ƒ}|Sr)rrRrdr)r!rSrQrkrTr#r#r$rR‘szBoxAdapter.rendercCs t|j|ƒS)z+ Pass calls to box widget. )r]rer^r#r#r$r`—szBoxAdapter.__getattr__N)F)F)r3r4r5r6Úno_cacher%rDr7rr)r+rer2rcrirlrmrorrrRr`r#r#r#r$rbEs ÿ  rbc@s eZdZdS)Ú PaddingErrorNr:r#r#r#r$rvŸsrvc@s¨eZdZeedddfdd„Zdd„Zdd„Zd d „Zd d „Z e ee ƒZ d d„Z dd„Z e e e ƒZd"dd„Zdd„Zd#dd„Zdd„Zdd„Zdd„Zdd„Zd d!„ZdS)$ÚPaddingNrcCsÊ|j |¡t|ƒtkrJ|ddvrJ|ddkr>|d}t}n |d}t}t|ƒtkr„|ddvr„|ddkrx|d}n|d}t}|dur�t}||_||_ t |t ƒ\|_ |_ t|t ƒ\|_|_||_dS)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 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 rightrxéN)Ú_Padding__superr%r=Útupler r rr ÚleftÚrightÚnormalize_alignrvÚ _align_typeÚ _align_amountÚnormalize_widthÚ _width_typeÚ _width_amountÚ min_width)r!r-ÚalignÚwidthr„r|r}r#r#r$r%£s.A    ÿ ÿ zPadding.__init__cCs|jtkrttgƒS|j ¡Sr)r‚r rgrr"r2r(r#r#r$r2s  zPadding.sizingcCs0t|j ¡|j|j|j|j|jd�}t|t j ƒS)N)r…r†r|r}r„) r>rzrDr…r†r|r}r„rrwr%©r!Úattrsr#r#r$rDs ûzPadding._repr_attrscCst|j|jƒS)z7 Return the padding alignment setting. )Úsimplify_alignrr€r(r#r#r$Ú _get_alignszPadding._get_aligncCst|tƒ\|_|_| ¡dS)z, Set the padding alignment. N)r~rvrr€r*)r!r…r#r#r$Ú _set_alignsÿ zPadding._set_aligncCst|j|jƒS)z+ Return the padding width. )Úsimplify_widthr‚rƒr(r#r#r$Ú _get_widthszPadding._get_widthcCst|tƒ\|_|_| ¡dS)z( Set the padding width. N)r�rvr‚rƒr*)r!r†r#r#r$Ú _set_width$sÿ zPadding._set_widthFcCsÊ| ||¡\}}|d}|||8}|jtkr>|j d|¡}n|j |f|dd…|¡}| ¡dkr”td|d| ¡ƒ}t|ƒ}|  |jg¡|St|ƒ}|  |jg¡|dksº|dkrÆ|  ||¡|S)Nrr#ryú ) Úpadding_valuesr‚r rrRZcolsrrcrZ set_dependsZpad_trim_left_right)r!rSrQr|r}rkrTr#r#r$rR-s     zPadding.renderc CsÄ|d}|jtkrD|jjd|d�\}}t||j|jt|d|j|jƒS|jt kr t ||j|j|j pfdƒ}|jj|f|d�\}}t||j|jt ||j |j|jƒSt||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.rr#rPN)r‚r rÚpackÚcalculate_left_right_paddingrr€r|r}r Úmaxr„rrƒ)r!rSrQrkr†ÚignoreÚmaxwidthr#r#r$r�Cs0 þ ÿ ÿ ý ýzPadding.padding_valuesc Csz|\}| ||¡\}}|jtkr@|j |||f|¡\}}|S|jtkr`|j d|¡\}} | S|jj|||f|d�S)z0Return the rows needed for self.original_widget.r#rP)r�r‚r rr‘r rc) r!rSrQrkr|r}ZpcolsZprowsZfcolsZfrowsr#r#r$rc[s ÿ z Padding.rowscCs@|d}| |d¡\}}|||f|dd…}|j ||¡S)z'Pass keypress to self._original_widget.rTryN)r�rrm)r!rSrnrkr|r}Úmaxvalsr#r#r$rmhszPadding.keypressc Cs~t|jdƒsdS| |d¡\}}|d}|||f|dd…}|ddkrRdS|j |¡}|durjdS|\}}|||fS)zDReturn the (x,y) coordinates of cursor within self._original_widget.riNTrry)r,rr�ri) r!rSr|r}rkr–ÚcoordsÚxÚyr#r#r$rios   zPadding.get_cursor_coordscCsŒt|jdƒsdS| |d¡\}}|d}|||f|dd…}t|ƒtkr|||kr\|}n|||krt||d}||8}|j |||¡S)z‹Set the cursor position with (x,y) coordinates of self._original_widget. Returns True if move succeeded, False otherwise. roTrryN)r,rr�r=Úintro)r!rSr˜r™r|r}rkr–r#r#r$ro~s    zPadding.move_cursor_to_coordsc Cstt|jdƒsdS| ||¡\}}|d} ||ks<|| |kr@dS| ||f|dd…} |j | ||||||¡S)z=Send mouse event if position is within self._original_widget.rrFrryN)r,rr�rr) r!rSrsrtr˜r™rQr|r}rkr–r#r#r$rr�s ÿzPadding.mouse_eventcCsft|jdƒsdS| |d¡\}}|d}|||f|dd…}|j |¡}t|ƒtkrb||S|S)z@Return the preferred column from self._original_widget, or None.rlNTrry)r,rr�rlr=rš)r!rSr|r}rkr–r˜r#r#r$rl�s   zPadding.get_pref_col)F)F)r3r4r5r rr%r2rDrŠr‹r7r…r�rŽr†rRr�rcrmrirorrrlr#r#r#r$rw¢s&ÿ `      rwc@s eZdZdS)Ú FillerErrorNr:r#r#r#r$r›ªsr›c@sˆeZdZeedddfdd„Zdd„Zdd„Zej Z ej Z e e e ƒZd d „Zd d „Zddd„Zdd„Zdd„Zdd„Zdd„Zdd„ZdS)ÚFillerNrcCs&|j |¡t|tƒr„|ddkrNt|tƒr8|ddkr@tdƒ‚|d}t}n6|ddkr„t|tƒrp|ddkrxtdƒ‚|d}t}t|tƒrÀ|ddkr¨|d}t}n|ddkrÀ|d}t}|dusÐ|tkrÔt }||_ ||_ t |tƒ\|_ |_t|tƒ\|_|_|jtt fv�r||_nd|_dS)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. rz fixed topz fixed bottomz:fixed top height may only be used with fixed bottom valignryz:fixed bottom height may only be used with fixed top valignN)Ú_Filler__superr%Ú isinstancer{r›rrrrr ÚtopÚbottomÚnormalize_valignÚ valign_typeÚ valign_amountÚnormalize_heightÚ height_typeÚ height_amountrÚ min_height)r!ÚbodyÚvalignrdr§rŸr r#r#r$r%®s@*       ÿ ÿ zFiller.__init__cCs ttgƒSr)rgrr(r#r#r$r2sz Filler.sizingcCs@t|j ¡t|j|jƒt|j|jƒ|j |j |j d�}t |t jƒS)N)r©rdrŸr r§)r>r�rDÚsimplify_valignr¢r£Úsimplify_heightr¥r¦rŸr r§rrœr%r‡r#r#r$rDs   ûzFiller._repr_attrscCs |j ¡S)zReturn selectable from body.r/r(r#r#r$r0szFiller.selectablec Csf|\}}|jtkrB|jj|f|d�}t||j|jt|d|j|j ƒSt||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. rPN) r¥r rrcÚcalculate_top_bottom_fillerr¢r£rrŸr r¦r§)r!rSrQrkÚmaxrowrdr#r#r$Ú filler_valuess  ý ýzFiller.filler_valuesFc CsÊ|\}}| ||¡\}}|jtkr4|j |f|¡}n|j ||||f|¡}t|ƒ}|rž| ¡|krž|jdurž|j\}} | |krž| | |d|||¡| ¡|krº| d|¡|S|  ||¡|S)z:Render self.original_widget with space above and/or below.Nryr) r®r¥r rrRrrcZcursorZtrimZpad_trim_top_bottom) r!rSrQrkr­rŸr rTZcxÚcyr#r#r$rR*s     z Filler.rendercCsP|\}}|jtkr"|j |f|¡S| ||fd¡\}}|j ||||f|¡S)z&Pass keypress to self.original_widget.T)r¥r rrmr®)r!rSrnrkr­rŸr r#r#r$rm@s  zFiller.keypressc Cs†|\}}t|jdƒsdS| |d¡\}}|jtkrB|j |f¡}n|j ||||f¡}|sbdS|\}}||krz|d}|||fS)z6Return cursor coords from self.original_widget if any.riNTry)r,rr®r¥r ri) r!rSrkr­rŸr r—r˜r™r#r#r$riIs  ÿzFiller.get_cursor_coordscCs^|\}}t|jdƒsdS|jtkr2|j |f¡}n(| |d¡\}}|j ||||f¡}|S)z1Return pref_col from self.original_widget if any.rlNT)r,rr¥r rlr®)r!rSrkr­r˜rŸr r#r#r$rl\s  ÿzFiller.get_pref_colcCs€|\}}t|jdƒsdS| |d¡\}}||ks<|||kr@dS|jtkr`|j |f|||¡S|j ||||f|||¡S)úPass to self.original_widget.roTF)r,rr®r¥r ro)r!rSrprqrkr­rŸr r#r#r$roks   ÿÿzFiller.move_cursor_to_coordsc CsŒ|\}}t|jdƒsdS| |d¡\} } || ks<||| kr@dS|jtkrf|j |f||||| |¡S|j ||| | f||||| |¡S)r°rrFT)r,rr®r¥r rr) r!rSrsrtrprqrQrkr­rŸr r#r#r$rr{s   ÿÿzFiller.mouse_event)F)r3r4r5rr r%r2rDrr)Zget_bodyr+Zset_bodyr7r¨r0r®rRrmrirlrorrr#r#r#r$rœ­s ÿ R    rœc@sHeZdZdZdgZdZdd„Zddd„Zd d „Zdd d „Z dd d„Z dS)Ú 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. rcTcCsdS©NFr#r(r#r#r$r0”szWidgetDisable.selectableFcCs|j |d¡Sr²)rrcrhr#r#r$rc–szWidgetDisable.rowscCs |j ¡Srr1r(r#r#r$r2˜szWidgetDisable.sizingcCs|j |d¡Sr²)rr‘rhr#r#r$r‘šszWidgetDisable.packcCs|j |d¡}t|ƒSr²)rrRr)r!rSrQrTr#r#r$rRœszWidgetDisable.renderN)F)F)F) r3r4r5r6ruZ ignore_focusr0rcr2r‘rRr#r#r#r$r±‹s  r±cCsP|tttfvr|dfSt|ƒtkr>t|ƒdkr>|dtkr>|S|d|fƒ‚dS)zy Split align into (align_type, align_amount). Raise exception err if align doesn't match a valid alignment. Nérzaalign value %r is not one of 'left', 'center', 'right', ('relative', percentage 0=left 100=right))r r r r=r{Úlenr)r…Úerrr#r#r$r~ s$þr~cCs|tkr||fS|S)zc Recombine (align_type, align_amount) into an align value. Inverse of normalize_align. ©r)Ú align_typeÚ align_amountr#r#r$r‰­sr‰cCsb|ttfvr|dfSt|ƒtkr(t|fSt|ƒtkrPt|ƒdkrP|dtkrP|S|d|fƒ‚dS)zy Split width into (width_type, width_amount). Raise exception err if width doesn't match a valid alignment. Nr³rzmwidth value %r is not one of fixed number of columns, 'pack', ('relative', percentage of total width), 'clip')r r r=ršrr{r´r)r†rµr#r#r$r�¶s  $þr�cCs$|ttfvr|S|tkr|S||fS)zc Recombine (width_type, width_amount) into an width value. Inverse of normalize_width. )r r r)Ú width_typeÚ width_amountr#r#r$rŒÅs  rŒcCsN|tttfvr|dfSt|tƒrt|||dƒ}t|d|dƒ} |durBt| |ƒ} n|} tdtdtdi} |  ||¡} || ||} |td| d| dƒ7}|| |}|dkr¦|krÈnnt|| ƒ} || 8}|| 7}n4|dkrÜ|krünnt|| ƒ} || 8}|| 7}t|dƒ}t|dƒ}||fS)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éeryNé2éd)rr“rrrrÚgetÚmin)r­r¢r£r¥r¦r§rŸr Z maxheightrdÚstandard_alignmentsr©ZfillerÚshiftr#r#r$r¬s,!        r¬cCs&|tkr>t|||dƒ}t|d|dƒ} |durBt| |ƒ} n|} tdtdtdi} |  ||¡} || ||} |td| d| dƒ7}|| |}|dkrÀ|dkrÀt|| ƒ} || 8}|| 7}n,|dkrì|dkrìt|| ƒ} || 8}|| 7}|tk�r|dk�s |dk�rt|dƒ}t|dƒ}||fS)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) rr»ryNr¼r½) rr“rr r r r¾r¿r )rkr·r¸r¹rºr„r|r}r•r†rÀr…ZpaddingrÁr#r#r$r’Es.%        r’cCsddl}| ¡dS)Nr)ÚdoctestZtestmod)rÂr#r#r$Ú_test�srÃÚ__main__N)8Z __future__rrZ urwid.utilrZ urwid.widgetrrrrr r r r r rrrrrrrZurwid.split_reprrZ urwid.canvasrrrrrrrr8r9r;rUÚ Exceptionrarbrvrwr›rœr±r~r‰r�rŒr¡rªr¤r«r¬r’rÃr3r#r#r#r$ÚsF H 8ÿ~ZZ _     BH