grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026a BjŒjRQã@sÒddlmZmZddlmZmZddlmZddlm Z ddl m Z m Z m Z mZmZmZmZmZmZmZmZmZmZmZmZmZddlmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'ddl(m)Z)m*Z*ddl+m,Z,m-Z-m.Z.m/Z/m0Z0Gd d „d e1ƒZ2Gd d „d e1ƒZ3Gd d„de4ƒZ5Gdd„dee2e3ƒZ6Gdd„de4ƒZ7Gdd„de e2e3ƒZ8Gdd„de4ƒZ9Gdd„de e2ƒZ:Gdd„de4ƒZ;Gdd„de e2e3ƒZd!d"„Z?e@d#k�rÎe?ƒd$S)%é)ÚdivisionÚprint_function)ÚchainÚrepeat)Úxrange)Úis_mouse_press)ÚWidgetÚDividerÚFLOWÚFIXEDÚPACKÚBOXÚ WidgetWrapÚGIVENÚWEIGHTÚLEFTÚRIGHTÚRELATIVEÚTOPÚBOTTOMÚCLIPÚ RELATIVE_100) ÚPaddingÚFillerÚcalculate_left_right_paddingÚcalculate_top_bottom_fillerÚnormalize_alignÚnormalize_widthÚnormalize_valignÚnormalize_heightÚsimplify_alignÚsimplify_widthÚsimplify_valignÚsimplify_height)Ú MonitoredListÚMonitoredFocusList)ÚCompositeCanvasÚ CanvasOverlayÚ CanvasCombineÚ SolidCanvasÚ CanvasJoinc@s0eZdZdZdd„Zdd„Zdd„Zdd „Zd S) ÚWidgetContainerMixinzQ Mixin class for widget containers implementing common container methods cCs|j|djS)aG Container short-cut for self.contents[position][0].base_widget which means "give me the child widget at position without any widget decorations". This allows for concise traversal of nested container widgets such as: my_widget[position0][position1][position2] ... r)ÚcontentsÚ base_widget©ÚselfZposition©r0ú5/usr/lib64/python3.9/site-packages/urwid/container.pyÚ __getitem__*s z WidgetContainerMixin.__getitem__cCsBg}|}z |j}Wnty(|YS0| |¡|jj}qdS)zµ Return the .focus_position values starting from this container and proceeding along each child widget until reaching a leaf (non-container) widget. N)Úfocus_positionÚ IndexErrorÚappendÚfocusr-)r/ÚoutÚwÚpr0r0r1Úget_focus_path7s    z#WidgetContainerMixin.get_focus_pathcCs*|}|D]}||jkr||_|jj}qdS)aÝ Set the .focus_position property starting from this container widget and proceeding along newly focused child widgets. Any failed assignment due do incompatible position types or invalid positions will raise an IndexError. This method may be used to restore a particular widget to the focus by passing in the value returned from an earlier call to get_focus_path(). positions -- sequence of positions N)r3r6r-)r/Z positionsr8r9r0r0r1Úset_focus_pathGs  z#WidgetContainerMixin.set_focus_pathcCs,g}|}|jj}|dur|S| |¡qdS)aW Return the .focus values starting from this container and proceeding along each child widget until reaching a leaf (non-container) widget. Note that the list does not contain the topmost container widget (i.e., on which this method is called), but does include the lowest leaf widget. N)r-r6r5)r/r7r8r0r0r1Úget_focus_widgetsZs z&WidgetContainerMixin.get_focus_widgetsN)Ú__name__Ú __module__Ú __qualname__Ú__doc__r2r:r;r<r0r0r0r1r+&s  r+c@s eZdZdZdd„Zdd„ZdS)Ú WidgetContainerListContentsMixinzs Mixin class for widget containers whose positions are indexes into a list available as self.contents. cCsttt|jƒƒƒS)z` Return an iterable of positions for this container from first to last. ©ÚiterrÚlenr,©r/r0r0r1Ú__iter__qsz)WidgetContainerListContentsMixin.__iter__cCsttt|jƒdddƒƒS)z` Return an iterable of positions for this container from last to first. ééÿÿÿÿrBrEr0r0r1Ú __reversed__xsz-WidgetContainerListContentsMixin.__reversed__N)r=r>r?r@rFrIr0r0r0r1rAlsrAc@s eZdZdS)Ú GridFlowErrorN©r=r>r?r0r0r0r1rJ€srJc@s<eZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z e ee dd�Z dd„Z dd„Z e e e dd�Zdd„Zdd„Ze eedd�Zedfdd„Zdd„Zdd „Ze ed!d�Zd"d#„Ze eed$d�Zd%d&„Zd'd(„Ze eed)d�Zd*d+„Zd,d-„Zd.d/„Zd0d1„Zd?d3d4„Z d@d5d6„Z!d7d8„Z"d9d:„Z#d;d<„Z$d=d>„Z%dS)AÚGridFlowz© The GridFlow widget is a flow widget that renders all the widgets it contains the same width and it arranges them from left to right and top to bottom. cCs ttgƒS©N)Ú frozensetr rEr0r0r1Úsizing‰szGridFlow.sizingcsŽt‡fdd„|Dƒƒˆ_ˆj ˆj¡ˆj ‡fdd„¡ˆj ˆj¡ˆˆ_|ˆ_|ˆ_ |ˆ_ dˆ_ ˆj   d¡ˆ |ˆt|ƒf¡dS)aÈ :param cells: list of flow widgets to display :param cell_width: column width for each cell :param h_sep: blank columns between each cell horizontally :param v_sep: blank rows between cells vertically (if more than one row is required to display all the cells) :param align: horizontal alignment of cells, one of: 'left', 'center', 'right', ('relative', percentage 0=left 100=right) csg|]}|tˆff‘qSr0©r)Ú.0r8)Ú cell_widthr0r1Ú –sz%GridFlow.__init__..csˆ ¡SrM©Ú _invalidate©ÚfrEr0r1Ú™óz#GridFlow.__init__..N)r%Ú _contentsÚset_modified_callbackrUÚset_focus_changed_callbackÚset_validate_contents_modifiedÚ_contents_modifiedÚ _cell_widthÚh_sepÚv_sepÚalignÚ _cache_maxcolÚ_GridFlow__superÚ__init__Úget_display_widgetrD)r/ÚcellsrRr`rarbr0)rRr/r1reŒs ÿ  zGridFlow.__init__cCsd|_|j ¡dSrM)rcrdrUrEr0r0r1rU¤szGridFlow._invalidatec CsP|D]F}z|\}\}}|tkr"t‚WqttfyHtd|fƒ‚Yq0qdS©Nzadded content invalid %r)rÚ ValueErrorÚ TypeErrorrJ©r/ÚslcÚ new_itemsÚitemr8ÚtÚnr0r0r1r^¨s zGridFlow._contents_modifiedcs0tdd„ˆjDƒƒ‰‡‡fdd„}ˆ |¡ˆS)Ncss|]\}}|VqdSrMr0©rQr8ror0r0r1Ú ²rYz&GridFlow._get_cells..csˆ ˆ¡dSrM)Ú _set_cellsr0©Úmlr/r0r1Ú user_modified³sz*GridFlow._get_cells..user_modified©r$r,r[©r/rvr0rtr1Ú _get_cells±s zGridFlow._get_cellscs0ˆj}‡fdd„|Dƒˆ_|t|ƒkr,|ˆ_dS)Ncsg|]}|tˆjff‘qSr0)rr_)rQÚnewrEr0r1rS¹sz'GridFlow._set_cells..)r3r,rD©r/Zwidgetsr3r0rEr1rs·s  ÿ zGridFlow._set_cellszò A list of the widgets in this GridFlow .. note:: only for backwards compatibility. You should use the new use the new standard container property :attr:`contents` to modify GridFlow contents. ©ÚdoccCs|jSrM)r_rEr0r0r1Ú_get_cell_widthÅszGridFlow._get_cell_widthcs,|j}‡fdd„|jDƒ|_||_ˆ|_dS)Ncsg|]\}}|tˆff‘qSr0rP©rQr8Úoptions©Úwidthr0r1rSÉsz,GridFlow._set_cell_width..)r3r,r_)r/r‚r3r0r�r1Ú_set_cell_widthÇs  ÿzGridFlow._set_cell_widthzg The width of each cell in the GridFlow. Setting this value affects all cells. cCs|jSrM©rZrEr0r0r1Ú _get_contentsÒszGridFlow._get_contentscCs||jdd…<dSrMr„©r/Úcr0r0r1Ú _set_contentsÔszGridFlow._set_contentsaè The contents of this GridFlow as a list of (widget, options) tuples. options is currently a tuple in the form `('fixed', number)`. number is the number of screen columns to allocate to this cell. 'fixed' is the only type accepted at this time. This list may be modified like a normal list and the GridFlow widget will update automatically. .. seealso:: Create new options tuples with the :meth:`options` method. NcCs,|tkrtd|fƒ‚|dur$|j}||fS)zÛ Return a new options tuple for use in a GridFlow's .contents list. width_type -- 'given' is the only value accepted width_amount -- None to use the default cell_width for this GridFlow úinvalid width_type: %rN)rrJr_)r/Ú width_typeÚ width_amountr0r0r1r€äs zGridFlow.optionscCst|tƒr| |¡S| |¡S)a7 Set the cell in focus, for backwards compatibility. .. note:: only for backwards compatibility. You may also use the new standard container property :attr:`focus_position` to get the focus. :param cell: contained element to focus :type cell: Widget or int )Ú isinstanceÚintÚ_set_focus_positionÚ_set_focus_cell)r/Úcellr0r0r1Ú set_focusñs  zGridFlow.set_focuscCs|js dS|j|jdS)zà Return the widget in focus, for backwards compatibility. .. note:: only for backwards compatibility. You may also use the new standard container property :attr:`focus` to get the focus. Nr©r,r3rEr0r0r1Ú get_focusÿszGridFlow.get_focusz8the child widget in focus or None when GridFlow is emptycCs>t|jƒD] \}\}}||kr ||_dSq td|fƒ‚dS)Nz)Widget not found in GridFlow contents: %r)Ú enumerater,r3ri)r/r�Úir8r€r0r0r1r� s zGridFlow._set_focus_cellaF The widget in focus, for backwards compatibility. .. note:: only for backwards compatibility. You should use the new use the new standard container property :attr:`focus` to get the widget in focus and :attr:`focus_position` to get/set the cell in focus by index. cCs|jstdƒ‚|jjS)zd Return the index of the widget in focus or None if this GridFlow is empty. z$No focus_position, GridFlow is empty©r,r4r6rEr0r0r1Ú_get_focus_positionszGridFlow._get_focus_positionc CsPz|dks|t|jƒkrt‚Wn$ttfyBtd|fƒ‚Yn0||j_dS)úf Set the widget in focus. position -- index of child widget to be made focus rz'No GridFlow child widget at position %sN©rDr,r4rjr6r.r0r0r1rŽ#s zGridFlow._set_focus_positionz“ index of child widget in focus. Raises :exc:`IndexError` if read when GridFlow is empty, or when set to an invalid index. cCs.|\}|j|kr|jS||_| |¡|_|jS)zž Arrange the cells into columns (and possibly a pile) for display, input or to calculate rows, and update the display widget. )rcÚ_wÚgenerate_display_widget)r/ÚsizeÚmaxcolr0r0r1rf4s   zGridFlow.get_display_widgetc Cs~|\}tƒ}|js|S|jdkr,|jd|_d}tgƒ}d}t|jƒD�]\}\}\} } |dusl||| kr¼|jr†|j || ¡f¡tg|j ƒ}d} t ||j ƒ} || _ |j | | ¡f¡|j || t | ¡f¡||jksê| sþ| ¡rþt|jƒd|_d} ||jk�rt|jƒd|_tdd„|jDƒƒ|j t|jƒ}| |k�rN|| _||j | _qF|j�rr|jdd…=n| ¡|S)zC Actually generate display widget (ignoring cache) rGNrFTcss|]}|ddVqdS)rGNr0)rQÚxr0r0r1rrhrYz3GridFlow.generate_display_widget..)r r,raÚtopÚPiler”r5r€ÚColumnsr`rrbÚfirst_positionrr3Ú selectablerDÚsumZoriginal_widgetr‚r^) r/rœr�Zdividerr‡r9Z used_spacer•r8rŠr‹Zcolumn_focusedZpadr0r0r1r›DsL     ÿÿ ÿ z GridFlow.generate_display_widgetcCs8|jj}|sdS|j}|jr$|j}nd}|j||_dS)zK Set the focus to the item in focus in the display widget. Nr)ršr6r-r3r¢)r/Z pile_focusr‡Zcol_focus_positionr0r0r1Ú_set_focus_from_display_widgetzs z'GridFlow._set_focus_from_display_widgetcCs,| |¡|j ||¡}|dur(| ¡|S)z_ Pass keypress to display widget for handling. Captures focus changes. N)rfrdÚkeypressr¥©r/rœÚkeyr0r0r1r¦“s  zGridFlow.keypressFcCs| |¡|jj||d�S)N©r6)rfrdÚrows©r/rœr6r0r0r1rªžs z GridFlow.rowscCs| |¡|j ||¡SrM)rfrdÚrenderr«r0r0r1r¬¢s zGridFlow.rendercCs| |¡|j |¡S)zGet cursor from display widget.)rfrdÚget_cursor_coords©r/rœr0r0r1r­¦s zGridFlow.get_cursor_coordscCs&| |¡|j |||¡}| ¡|S)z/Set the widget in focus based on the col + row.)rfrdÚmove_cursor_to_coordsr¥)r/rœÚcolÚrowÚrvalr0r0r1r¯«s zGridFlow.move_cursor_to_coordscCs,| |¡|j ||||||¡| ¡dS)NT)rfrdÚ mouse_eventr¥)r/rœÚeventÚbuttonr°r±r6r0r0r1r³²s zGridFlow.mouse_eventcCs| |¡|j |¡S)z$Return pref col from display widget.)rfrdÚ get_pref_colr®r0r0r1r¶¸s zGridFlow.get_pref_col)F)F)&r=r>r?r@rOrerUr^ryrsÚpropertyrgr~rƒrRr…rˆr,rr€r‘r“r6r�Z focus_cellr—rŽr3rfr›r¥r¦rªr¬r­r¯r³r¶r0r0r0r1rLƒsF   ÿ  6  rLc@s eZdZdS)Ú OverlayErrorNrKr0r0r0r1r¸¿sr¸c@sðeZdZdZdZeegƒZede dddde de ddddfZ d+dd„Z e d,dd „ƒZd-d d „Zd d „Zdd„Zdd„Zeedd�Zdd„Zdd„Zeeedd�Zdd„Zdd„Zdd„Zeedd�Zd d!„Zd"d#„Zd$d%„Zd.d'd(„Zd)d*„Z dS)/ÚOverlayzN Overlay contains two box widgets and renders one on top of the other TNédrc Cs6|j ¡||_||_| ||||||| | | | ¡ dS)a° :param top_w: a flow, box or fixed widget to overlay "on top" :type top_w: Widget :param bottom_w: a box widget to appear "below" previous widget :type bottom_w: Widget :param align: alignment, one of ``'left'``, ``'center'``, ``'right'`` or (``'relative'``, *percentage* 0=left 100=right) :type align: str :param width: width type, one of: ``'pack'`` if *top_w* is a fixed widget *given width* integer number of columns wide (``'relative'``, *percentage of total width*) make *top_w* width related to container width :param valign: alignment mode, one of ``'top'``, ``'middle'``, ``'bottom'`` or (``'relative'``, *percentage* 0=top 100=bottom) :param height: one of: ``'pack'`` if *top_w* is a flow or fixed widget *given height* integer number of rows high (``'relative'``, *percentage of total height*) make *top_w* height related to container height :param min_width: the minimum number of columns for *top_w* when width is not fixed :type min_width: int :param min_height: minimum number of rows for *top_w* when height is not fixed :type min_height: int :param left: a fixed number of columns to add on the left :type left: int :param right: a fixed number of columns to add on the right :type right: int :param top: a fixed number of rows to add on the top :type top: int :param bottom: a fixed number of rows to add on the bottom :type bottom: int Overlay widgets behave similarly to :class:`Padding` and :class:`Filler` widgets when determining the size and position of *top_w*. *bottom_w* is always rendered the full size available "below" *top_w*. N)Z_Overlay__superreÚtop_wÚbottom_wÚset_overlay_parameters) r/r»r¼rbr‚ÚvalignÚheightÚ min_widthÚ min_heightÚleftÚrightrŸÚbottomr0r0r1reÍs 0   ÿzOverlay.__init__cCs |||||| | ||||| | | fS)an Return a new options tuple for use in this Overlay's .contents mapping. This is the common container API to create options for replacing the top widget of this Overlay. It is provided for completeness but is not necessarily the easiest way to change the overlay parameters. See also :meth:`.set_overlay_parameters` r0)Ú align_typeÚ align_amountrŠr‹Ú valign_typeÚ valign_amountÚ height_typeÚ height_amountrÀrÁrÂrÃrŸrÄr0r0r1r€s   þzOverlay.optionsc Csˆt|tƒr<|ddkr$|d}t}n|ddkr<|d}t}t|tƒrx|ddkr`|d}t}n|ddkrx|d}t}t|tƒr´|ddkrœ|d} t}n|ddkr´|d} t}t|tƒrð|ddkrØ|d} t}n|ddkrð|d} t}|durüt}|du�r t}t|t ƒ\} } t |t ƒ\} }t |t ƒ\}}t |t ƒ\}}|t tfv�rTd}|j| | | | |||||||||| | ¡f|jd<dS)z’ Adjust the overlay size and position parameters. See :class:`__init__() ` for a description of the parameters. rz fixed leftrGz fixed rightz fixed topz fixed bottomN)rŒÚtuplerrrrrr rr¸rrrrr»r€r,)r/rbr‚r¾r¿rÀrÁrÂrÃrŸrÄrÅrÆrŠr‹rÇrÈrÉrÊr0r0r1r½sV              ýzOverlay.set_overlay_parameterscCs |j ¡S)zReturn selectable from top_w.)r»r£rEr0r0r1r£OszOverlay.selectablecCs$|j |j|g| |d¡¢RŽ|¡S)zPass keypress to top_w.T)r»r¦Ú top_w_sizeÚcalculate_padding_fillerr§r0r0r1r¦Ss  ÿÿzOverlay.keypresscCs|jS)zH Currently self.top_w is always the focus of an Overlay )r»rEr0r0r1Ú _get_focusXszOverlay._get_focusz1the top widget in this overlay is always in focusr|cCsdS)zF Return the top widget position (currently always 1). rGr0rEr0r0r1r—`szOverlay._get_focus_positioncCs|dkrtd|fƒ‚dS)zŽ Set the widget in focus. Currently only position 0 is accepted. position -- index of child widget to be made focus rGzGOverlay widget focus_position currently must always be set to 1, not %sN)r4r.r0r0r1rŽesÿzOverlay._set_focus_positionz2index of child widget in focus, currently always 1csG‡fdd„dtƒ}|ƒS)Ncs eZdZdd„Z”jZ”jZdS)z*Overlay._contents..OverlayContentscSsdS)Nér0©Ú inner_selfr0r0r1Ú__len__ssz2Overlay._contents..OverlayContents.__len__N)r=r>r?rÒÚ_contents__getitem__r2Ú_contents__setitem__Ú __setitem__r0rEr0r1ÚOverlayContentsrsrÖ©Úobject)r/rÖr0rEr1rZqszOverlay._contentscCsp|dkr|j|jfS|dkr^|j|j|j|j|j|j|j|j |j |j |j |j |j|j|jffStd|fƒ‚dS)NrrGú#Overlay.contents has no position %r)r¼Ú_DEFAULT_BOTTOM_OPTIONSr»rÅrÆrŠr‹rÀrÂrÃrÇrÈrÉrÊrÁrŸrÄr4)r/Úindexr0r0r1rÓxs   úÿzOverlay._contents__getitem__cCsrz |\}}Wn$ttfy0td|fƒ‚Yn0|dkr^||jkrTtd|jfƒ‚||_�n|dk�rXz$|\}}}}} } } } } }}}}}Wn$ttfy°td|fƒ‚Yn0tt||ƒtƒ\}}tt||ƒtƒ\}}t t | | ƒtƒ\} }t t ||ƒtƒ\}}||_ ||_||_||_| |_| |_||_||_| |_| |_||_||_| |_||_ntd|fƒ‚| ¡dS)Núadded content invalid: %rrz bottom_options must be set to %rrGztop_options is invalid: %rrÙ)rirjr¸rÚr¼rr rr!rr"rr#rÅrÆrŠr‹rÇrÈrÉrÊrÂrÃrŸrÄrÀrÁr4rU)r/rÛÚvalueÚvalue_wÚ value_optionsrÅrÆrŠr‹rÀrÂrÃrÇrÈrÉrÊrÁrŸrÄZ valign_amounr0r0r1rÔ…sf  ÿ  ý   þÿ  ÿ ÿ ÿ ÿÿzOverlay._contents__setitem__a- a list-like object similar to:: [(bottom_w, bottom_options)), (top_w, top_options)] This object may be used to read or update top and bottom widgets and top widgets's options, but no widgets may be added or removed. `top_options` takes the form `(align_type, align_amount, width_type, width_amount, min_width, left, right, valign_type, valign_amount, height_type, height_amount, min_height, top, bottom)` bottom_options is always `('left', None, 'relative', 100, None, 0, 0, 'top', None, 'relative', 100, None, 0, 0)` which means that bottom widget always covers the full area of the Overlay. writing a different value for `bottom_options` raises an :exc:`OverlayError`. c Cspt|jdƒsdS|\}}| |d¡\}}}}|j ||||||f¡\}} | |kr`|d} ||| |fS)z(Return cursor coords from top_w, if any.r­NTrG)Úhasattrr»rÍr­) r/rœr�ÚmaxrowrÂrÃrŸrÄržÚyr0r0r1r­És ÿ ÿzOverlay.get_cursor_coordsc CsN|\}}d}|jtkrZ|jjd|d�\}}|s6tdƒ‚t||j|jt|d|j |j ƒ\}}n(t||j|j|j|j |j |j |j ƒ\}}|rÆt ||j|jt|d|j|jƒ\} } || | |krÄ|| |} n||jtk�r|jj|f|d�}t ||j|jt|d|j|jƒ\} } ||k�rB||} n(t ||j|j|j|j|j|j|jƒ\} } ||| | fS)z1Return (padding left, right, filler top, bottom).Nr0r©zfixed widget must have a height)rŠr r»Úpackr¸rrÅrÆrrÂrÃr‹rÀrrÇrÈrrŸrÄrÉrªrÊrÁ) r/rœr6r�rár¿r‚rÂrÃrŸrÄr0r0r1rÍÖsH   þ  ýþ þ   ýz Overlay.calculate_padding_fillercCsP|jtkrdS|\}}|jtkr8|jtkr8|||fS||||||fS)z!Return the size to pass to top_w.r0)rŠr rÉ)r/rœrÂrÃrŸrÄr�rár0r0r1rÌýs  zOverlay.top_w_sizeFc Csº| ||¡\}}}}|j |¡}| ¡r0| ¡s8t|ƒS|j | |||||¡|¡}t|ƒ}|dksl|dkr„| t d|ƒt d|ƒ¡|dks”|dkr¬|  t d|ƒt d|ƒ¡t ||||ƒS)z#Render top_w overlayed on bottom_w.r) rÍr¼r¬Úcolsrªr&r»rÌÚpad_trim_left_rightÚminÚpad_trim_top_bottomr') r/rœr6rÂrÃrŸrÄZbottom_cZtop_cr0r0r1r¬ sÿ  ÿzOverlay.renderc Cs„t|jdƒsdS| ||¡\}}} } |\} } ||ksT|| |ksT|| ksT|| | krXdS|j | |||| | ¡|||||| |¡S)z0Pass event to top_w, ignore if outside of top_w.r³F)ràr»rÍr³rÌ) r/rœr´rµr°r±r6rÂrÃrŸrÄr�rár0r0r1r³s  ÿ ÿ ÿþzOverlay.mouse_event)NNrrrr)NNrrrr)NNrrrr)F)!r=r>r?r@Ú _selectablerNr Ú_sizingrrrrÚreÚ staticmethodr€r½r£r¦rÎr·r6r—rŽr3rZrÓrÔr,r­rÍrÌr¬r³r0r0r0r1r¹ÂsB þÿ 8þ ÿ 9ÿ ÿ .  ' r¹c@s eZdZdS)Ú FrameErrorNrKr0r0r0r1rë-srëc@seZdZdZdZeegƒZd8dd„Zdd„Z d d „Z e e e ƒZ d d „Z d d„Ze e eƒZdd„Zdd„Ze eeƒZdd„Zdd„Zdd„Ze edd�Ze eedd�Zdd„Zdd„Zd d!„Zd"d#„Zd$d%„Ze ed&d�Zd'd(„Zd)d*„Zd9d,d-„Z d.d/„Z!d0d1„Z"d2d3„Z#d4d5„Z$d6d7„Z%dS):ÚFramea€ Frame widget is a box widget with optional header and footer flow widgets placed above and below the box widget. .. note:: The main difference between a Frame and a :class:`Pile` widget defined as: `Pile([('pack', header), body, ('pack', footer)])` is that the Frame will not automatically change focus up and down in response to keystrokes. TNÚbodycCs&|j ¡||_||_||_||_dS)au :param body: a box widget for the body of the frame :type body: Widget :param header: a flow widget for above the body (or None) :type header: Widget :param footer: a flow widget for below the body (or None) :type footer: Widget :param focus_part: 'header', 'footer' or 'body' :type focus_part: str N)Z _Frame__superreÚ_headerÚ_bodyÚ_footerÚ focus_part)r/ríÚheaderÚfooterrñr0r0r1re>s zFrame.__init__cCs|jSrM)rîrEr0r0r1Ú get_headerPszFrame.get_headercCs*||_|dur|jdkrd|_| ¡dS)Nròrí)rîrñrU)r/ròr0r0r1Ú set_headerRszFrame.set_headercCs|jSrM)rïrEr0r0r1Úget_bodyYszFrame.get_bodycCs||_| ¡dSrM)rïrU)r/rír0r0r1Úset_body[szFrame.set_bodycCs|jSrM)rðrEr0r0r1Ú get_footer`szFrame.get_footercCs*||_|dur|jdkrd|_| ¡dS)Nrórí)rðrñrU)r/rór0r0r1Ú set_footerbszFrame.set_footercCsZ|dvrtd|fƒ‚|dkr(|jdus:|dkrH|jdurHtd|fƒ‚||_| ¡dS)a( Determine which part of the frame is in focus. .. note:: included for backwards compatibility. You should rather use the container property :attr:`.focus_position` to set this value. :param part: 'header', 'footer' or 'body' :type part: str ©ròrórízInvalid position for Frame: %sròNrózThis Frame has no %s)r4rîrðrñrU)r/Úpartr0r0r1r‘is ÿÿzFrame.set_focuscCs|jS)a2 Return an indicator which part of the frame is in focus .. note:: included for backwards compatibility. You should rather use the container property :attr:`.focus_position` to get this value. :returns: one of 'header', 'footer' or 'body'. :rtype: str )rñrEr0r0r1r“{s zFrame.get_focuscCs|j|j|jdœ|jS)Nrú)rîrðrïrñrEr0r0r1r·s ýüzFrame._get_focuszq child :class:`Widget` in focus: the body, header or footer widget. This is a read-only property.r|z� writeable property containing an indicator which part of the frame that is in focus: `'body', 'header'` or `'footer'`. csG‡fdd„dtƒ}|ƒS)NcsFeZdZdd„Zdd„Zdd„Zd dd „Z”jZ”j Z ”j Z ”j ZdS) z&Frame._contents..FrameContentscSs t| ¡ƒSrM)rDÚkeysrÐr0r0r1rÒ˜sz.Frame._contents..FrameContents.__len__cs‡fdd„ˆ ¡DƒS)Ncsg|]}|ˆ|f‘qSr0r0©rQÚkrÐr0r1rS›rYz@Frame._contents..FrameContents.items..©rürÐr0rÐr1Úitemsšsz,Frame._contents..FrameContents.itemscs‡fdd„ˆ ¡DƒS)Ncsg|] }ˆ|‘qSr0r0rýrÐr0r1rS�rYzAFrame._contents..FrameContents.values..rÿrÐr0rÐr1Úvaluesœsz-Frame._contents..FrameContents.valuesNc[s\|rBt|ddƒ}|r,|D]}||||<qn|D]\}}|||<q0|D]}||||<qFdS)Nrü)Úgetattr)rÑÚEÚFrürþÚvr0r0r1Úupdatežs   z-Frame._contents..FrameContents.update)N)r=r>r?rÒrrrÚ_contents_keysrürÓr2rÔrÕÚ_contents__delitem__Ú __delitem__r0rEr0r1Ú FrameContents—s r r×)r/r r0rEr1rZ–szFrame._contentscCs*dg}|jr| d¡|jr&| d¡|S)Nríròró)rîr5rð)r/rür0r0r1r®s   zFrame._contents_keyscCsT|dkr|jdfS|dkr*|jr*|jdfS|dkrB|jrB|jdfStd|fƒ‚dS)NríròróúFrame.contents has no key: %r)rïrîrðÚKeyError©r/r¨r0r0r1rÓµs   zFrame._contents__getitem__c Cs~|dvrtd|fƒ‚z|\}}|dur,t‚Wn$ttfyRtd|fƒ‚Yn0|dkrd||_n|dkrt||_n||_dS)N)ríròrór rÜríró)r rirjrërírórò)r/r¨rÝrÞrßr0r0r1rÔ½szFrame._contents__setitem__cCsb|dvrtd|fƒ‚|dkr(|jdus:|dkrH|jdurHtd|fƒ‚|dkrXd|_nd|_dS)N)ròróz#Frame.contents can't remove key: %rròrór )r rîrðròrór r0r0r1rÌsÿÿzFrame._contents__delitem__a# a dict-like object similar to:: { 'body': (body_widget, None), 'header': (header_widget, None), # if frame has a header 'footer': (footer_widget, None) # if frame has a footer } This object may be used to read or update the contents of the Frame. The values are similar to the list-like .contents objects used in other containers with (:class:`Widget`, options) tuples, but are constrained to keys for each of the three usual parts of a Frame. When other keys are used a :exc:`KeyError` will be raised. Currently all options are `None`, but using the :meth:`options` method to create the options value is recommended for forwards compatibility. cCsdS)z~ There are currently no options for Frame contents. Return None as a placeholder for future options. Nr0rEr0r0r1r€ësz Frame.optionsc CsL|\}}d}}|jr0|j |f|jdko,|¡}|jrP|j |f|jdkoL|¡}|}|jdkr˜||krvd|f||ffS||8}||kr–||f||ffSn¤|jdkrÜ||krº|df||ffS||8}||krÚ||f||ffSn`|||k�r   ÿ  ÿ  zFrame.frame_top_bottomFcCs®|\}}| ||f|¡\\}}\}}g} g} d} |r`||kr`t|jdƒ ||f|oZ|jdk¡} n2|r’|j |f|oz|jdk¡} |  ¡|ks’Jdƒ‚| r¸|  | d|jdkf¡|  |j¡|||k�r |j ||||f|oæ|jdk¡} |  | d|jdkf¡|  |j¡d} |�rF||k�rFt|jdƒ ||f|�o@|jdk¡} n8|�r~|j |f|�od|jdk¡} |  ¡|k�s~Jdƒ‚| �r¦|  | d|jdkf¡|  |j¡t | ƒS)NrŸròzrows, render mismatchrírÄró) rrròr¬rñrªr5rírór()r/rœr6r�ráÚhtrimÚftrimrrÚ combinelistZ depends_onÚheadríZfootr0r0r1r¬)s^ÿ   þ  ÿÿ  ÿÿ  þ ÿÿ z Frame.rendercCsâ|\}}|jdkr:|jdur:|j ¡s*|S|j |f|¡S|jdkrl|jdurl|j ¡s\|S|j |f|¡S|jdkrz|S|}|jdurš||j |f¡8}|jdur¶||j |f¡8}|dkrÂ|S|j ¡sÐ|S|j ||f|¡S)z!Pass keypress to widget in focus.ròNrórír)rñròr£r¦rórªrí)r/rœr¨r�rárr0r0r1r¦Ws(       zFrame.keypressc Csf|\}}| ||f|¡\\} } \} } || kr†|o8|jdk}t|ƒr^|dkr^|j ¡r^| d¡t|jdƒsndS|j |f|||||¡S||| krô|ož|jdk}t|ƒrÄ|dkrÄ|j ¡rÄ| d¡t|jdƒsÔdS|j |f|||||| |¡S|�o|jdk}t|ƒ�r.|dk�r.|j  ¡�r.| d¡t|j dƒ�s@dS|j  ||| | f||||| |¡S)zp Pass mouse event to appropriate part of frame. Focus may be changed on button 1 press. ròrGr³Frórí) rrñrròr£r‘ràr³rórí) r/rœr´rµr°r±r6r�rárrrrr0r0r1r³qsBÿ    ÿ     ÿ  ÿzFrame.mouse_eventc Cs¸|j ¡sdSt|jdƒsdS|j}|\}}| |d¡\\}}}|dkr\d}|j |f¡} n<|dkr‚|}|j ||||f¡} n||}|j |f¡} | dur¤dS| \} } | | |fS)ú2Return the cursor coordinates of the focus widget.Nr­Tròrrí) r6r£ràr3rròr­ríró) r/rœÚfpr�rárrÚ_Z row_adjustÚcoordsržrâr0r0r1r­™s&  zFrame.get_cursor_coordsccs"|jr dVdV|jrdVdS)zT Return an iterator over the positions in this Frame top to bottom. ròríróN)rîrðrEr0r0r1rF´s zFrame.__iter__ccs"|jr dVdV|jrdVdS)zT Return an iterator over the positions in this Frame bottom to top. róríròN)rðrîrEr0r0r1rI¾s zFrame.__reversed__)NNrí)F)&r=r>r?r@rèrNr rérerôrõr·ròrör÷rírørùrór‘r“rÎr6r3rZrrÓrÔrr,r€rr¬r¦r³r­rFrIr0r0r0r1rì0s@         6 .( rìc@s eZdZdS)Ú PileErrorNrKr0r0r0r1rÉsrc@s@eZdZdZeeegƒZdd.d/„Z"d0d1„Z#d?d2d3„Z$d4d5„Z%d6d7„Z&d8d9„Z'd:d;„Z(dS)@r zA A pile of widgets stacked vertically from top to bottom Nc s€dˆ_ˆj ¡tƒˆ_ˆj ˆj¡ˆj ‡fdd„¡ˆj ˆj ¡|}t |ƒD�]\}}|}t |t ƒs‚ˆj  |tdff¡nÂ|dttfvr°|\}}ˆj  |tdff¡n”t|ƒdkrÚ|\}}ˆj  |t|ff¡nj|dtk�r|\}}}ˆj  |t|ff¡n<|dtk�r6|\}}}ˆj  |||ff¡ntd|fƒ‚|durT| ¡rT|}qTˆj �rv|du�rvˆ |¡dˆ_dS) aX :param widget_list: child widgets :type widget_list: iterable :param focus_item: child widget that gets the focus initially. Chooses the first selectable widget if unset. :type focus_item: Widget or int *widget_list* may also contain tuples such as: (*given_height*, *widget*) always treat *widget* as a box widget and give it *given_height* rows, where given_height is an int (``'pack'``, *widget*) allow *widget* to calculate its own height by calling its :meth:`rows` method, ie. treat it as a flow widget. (``'weight'``, *weight*, *widget*) if the pile is treated as a box widget then treat widget as a box widget with a height based on its relative weight value, otherwise treat the same as (``'pack'``, *widget*). Widgets not in a tuple are the same as (``'weight'``, ``1``, *widget*)` .. note:: If the Pile is treated as a box widget there must be at least one ``'weight'`` tuple in :attr:`widget_list`. Fcsˆ ¡SrMrTrVrEr0r1rXðrYzPile.__init__..rGrNrÏz#initial widget list item invalid %r)rèZ _Pile__superrer%rZr[r^r\r]Ú_validate_contents_modifiedr”rŒrËr,r5rr r rDrr rr£r‘Úpref_col) r/Ú widget_listÚ focus_itemr•Úoriginalr8rWr¿Ú_ignorer0rEr1reÒs>     ÿ z Pile.__init__cCs"tdd„|jDƒƒ|_| ¡dS)úv Recalculate whether this widget should be selectable whenever the contents has been changed. css|]\}}| ¡VqdSrM©r£©rQr8Úor0r0r1rrrYz*Pile._contents_modified..N©Úanyr,rèrUrEr0r0r1r^szPile._contents_modifiedc CsV|D]L}z"|\}\}}|tttfvr(t‚WqttfyNtd|fƒ‚Yq0qdS)NrÜ)r rrrirjrrkr0r0r1rs z Pile._validate_contents_modifiedcs0tdd„ˆjDƒƒ‰‡‡fdd„}ˆ |¡ˆS)Ncss|]\}}|VqdSrMr0rqr0r0r1rr!rYz(Pile._get_widget_list..csˆ ˆ¡dSrM©Ú_set_widget_listr0rtr0r1rv"sz,Pile._get_widget_list..user_modifiedrwrxr0rtr1Ú_get_widget_list s zPile._get_widget_listc CsF|j}dd„t|t|jtdtdffƒƒƒDƒ|_|t|ƒkrB||_dS)NcSsg|]\}\}}||f‘qSr0r0©rQrzr8r€r0r0r1rS(sz)Pile._set_widget_list..rG©r3Úziprr,rrrDr{r0r0r1r)&sþÿ zPile._set_widget_listzº A list of the widgets in this Pile .. note:: only for backwards compatibility. You should use the new standard container property :attr:`contents`. r|cs0tdd„ˆjDƒƒ‰‡‡fdd„}ˆ |¡ˆS)Ncss.|]&\}\}}tttti ||¡|fVqdSrM©rr r r Úget)rQr8rWr¿r0r0r1rr6s ÿz'Pile._get_item_types..csˆ ˆ¡dSrM)Ú_set_item_typesr0rtr0r1rv:sz+Pile._get_item_types..user_modifiedrwrxr0rtr1Ú_get_item_types5s ý zPile._get_item_typescCs4|j}dd„t||jƒDƒ|_|t|ƒkr0||_dS)NcSs4g|],\\}}\}}|tttti ||¡|ff‘qSr0©r rr r r/)rQÚnew_tZ new_heightr8r€r0r0r1rS@sÿz(Pile._set_item_types..©r3r-r,rD)r/Ú item_typesr3r0r0r1r0>s  ý zPile._set_item_typeszÎ A list of the options values for widgets in this Pile. .. note:: only for backwards compatibility. You should use the new standard container property :attr:`contents`. cCs|jSrMr„rEr0r0r1r…MszPile._get_contentscCs||jdd…<dSrMr„r†r0r0r1rˆOszPile._set_contentsa� The contents of this Pile as a list of (widget, options) tuples. options currently may be one of (``'pack'``, ``None``) allow widget to calculate its own height by calling its :meth:`rows ` method, i.e. treat it as a flow widget. (``'given'``, *n*) Always treat widget as a box widget with a given height of *n* rows. (``'weight'``, *w*) If the Pile itself is treated as a box widget then the value *w* will be used as a relative weight for assigning rows to this box widget. If the Pile is being treated as a flow widget then this is the same as (``'pack'``, ``None``) and the *w* value is ignored. If the Pile itself is treated as a box widget then at least one widget must have a (``'weight'``, *w*) options value, or the Pile will not be able to grow to fill the required number of rows. This list may be modified like a normal list and the Pile widget will updated automatically. .. seealso:: Create new options tuples with the :meth:`options` method rGcCs2|tkrtdfS|ttfvr*td|fƒ‚||fS)a, Return a new options tuple for use in a Pile's :attr:`contents` list. :param height_type: ``'pack'``, ``'given'`` or ``'weight'`` :param height_amount: ``None`` for ``'pack'``, a number of rows for ``'fixed'`` or a weight value (number) for ``'weight'`` Nzinvalid height_type: %r)r rrr)rÉrÊr0r0r1r€ls  z Pile.optionscCsRt|tƒr| |¡St|jƒD] \}\}}||kr||_dSqtd|fƒ‚dS)aT Set the item in focus, for backwards compatibility. .. note:: only for backwards compatibility. You should use the new standard container property :attr:`focus_position`. to set the position by integer index instead. :param item: element to focus :type item: Widget or int Nz%Widget not found in Pile contents: %r©rŒr�rŽr”r,r3ri©r/rnr•r8r€r0r0r1r‘|s  zPile.set_focuscCs|js dS|j|jdS©z¹ Return the widget in focus, for backwards compatibility. You may also use the new standard container property .focus to get the child widget in focus. Nrr’rEr0r0r1r“�szPile.get_focusz4the child widget in focus or None when Pile is emptyaL A property for reading and setting the widget in focus. .. note:: only for backwards compatibility. You should use the new standard container properties :attr:`focus` and :attr:`focus_position` to get the child widget in focus or modify the focus position. cCs|jstdƒ‚|jjS)z` Return the index of the widget in focus or None if this Pile is empty. z No focus_position, Pile is emptyr–rEr0r0r1r—¦szPile._get_focus_positionc CsPz|dks|t|jƒkrt‚Wn$ttfyBtd|fƒ‚Yn0||j_dS)r˜rz#No Pile child widget at position %sNr™r.r0r0r1rŽ®s zPile._set_focus_positionz� index of child widget in focus. Raises :exc:`IndexError` if read when Pile is empty, or when set to an invalid index. cCs| ¡s dS| |¡|jS)z4Return the preferred column for the cursor, or None.N)r£Ú_update_pref_col_from_focusrr®r0r0r1r¶¿s zPile.get_pref_colc Csd|d}|j|\}\}}|tkr*||fS|tkrZt|ƒdkrZ|sN| ||¡}|||fS|fSdS)zU Return a size appropriate for passing to self.contents[i][0].render rrÏN)r,rrrDÚ get_item_rows) r/rœr•r6Ú item_rowsr�r8rWr¿r0r0r1Ú get_item_sizeÆs  zPile.get_item_sizec Csˆd}|d}t|ƒdkr |d}g}|durx|jD]@\}\}}|tkrR| |¡q2| |j|f|oj|j|kd�¡q2|Sd} |jD]€\}\}}|tkrÄ|j|f|oª|j|kd�} | | ¡|| 8}q‚|tkrà| |¡||8}q‚|rø| d¡| |7} q‚| d¡q‚| dk�rtdƒ‚|dk�r$d}t|jƒD]T\} \}\}}|| } | du�r.t t |ƒ|| dƒ} | || <|| 8}| |8} �q.|S)zb Return a list of the number of rows used by each widget in self.contents NrrÏrGr©z:No weighted widgets found for Pile treated as a box widgetçà?) rDr,rr5rªrr rr”r�Úfloat) r/rœr6rr�Úlr8rWr¿Úwtotalrªr•Zlir0r0r1r:ÕsL    ÿ            zPile.get_item_rowsFcCsB|d}d}g}t|jƒD]¶\}\}\}} |j|k} d} |tkrX|j|| f|oP| d�} nd|tkslt|ƒdkr‚|j|f|oz| d�} n:|dur–| ||¡}||} | dkr¼|j|| f|o¶| d�} | r| | || f¡q|söt d|d|dd…ddƒSt |ƒ} t|ƒdk�r>|d|   ¡k�r>t | ƒ} |   d|d|   ¡¡| S)Nrr©rGú ©rrÏ)r”r,rrr¬r rDr:r5r)r(rªr&rç)r/rœr6r�r;rr•r8rWr¿Z item_focusÚcanvrªr7r0r0r1r¬ s0    z Pile.renderc Csü| ¡s dSt|jdƒsdS|j}|j|\}\}}d}|d}|tks\|tkršt|ƒdkrš|tkrj|}n|dur€|j|dd�}||}|j  ||f¡} n|j  |f¡} | dur´dS| \} } |dkrô|durÚ|j|dd�}|d|…D] } | | 7} qæ| | fS)rNr­rrÏTr©) r£ràrr3r,rrrDr:r­) r/rœr•r8rWr¿r;r�rárržrâÚrr0r0r1r­)s2  zPile.get_cursor_coordscCst| ||¡ƒSrM)r¤r:r«r0r0r1rªIsz Pile.rowsc Csl|js |Sd}t|ƒdkr(|j|dd�}|j}| ¡rf| ||d|¡}|j ||¡}|j|dvrf|S|j|dkrŠt t |dddƒƒ}nt t |dt|jƒƒƒ}|s´|j|dd�}|D]®}|j|d  ¡sÐq¸|  |¡||_t |jd ƒsòdS||}|j|dk�r t t |dddƒƒ} n t t |ƒƒ} | D]0} | ||d|¡}|j  ||j| ¡�r0�qb�q0dS|S) zjPass the keypress to the widget in focus. Unhandled 'up' and 'down' keys may cause a focus change.NrÏTr©)ú cursor upú cursor downrErGrHrr¯)r,rDr:r3r£r<r6r¦Ú _command_mapÚlistÚranger9ràrr¯r) r/rœr¨r;r•ÚtsizeÚ candidatesÚjrªZrowlistr±r0r0r1r¦LsF    ÿ z Pile.keypresscCsBt|jdƒsdS|j}| ||d¡}|j |¡}|dur>||_dS)z+Update self.pref_col from the focus widget.r¶NT)ràr6r3r<r¶r)r/rœr•rJrr0r0r1r9}s  z Pile._update_pref_col_from_focusc Cs¬||_d}d}| ||¡}tt|dd„|jDƒƒƒD]$\}\}} |||krPq^||7}q4dS|  ¡sjdSt| dƒr¢| ||||¡} |  | |||¡} | dur¢dS||_ dS)z#Capture pref col and set new focus.Trcss|]\}}|VqdSrMr0rr0r0r1rr‘rYz-Pile.move_cursor_to_coords..Fr¯) rr:r”r-r,r£ràr<r¯r3) r/rœr°r±r6Úwrowr;r•rDr8rJr²r0r0r1r¯ˆs( ÿ   zPile.move_cursor_to_coordsc Cs¶d}| ||¡}tt|dd„|jDƒƒƒD]$\} \} } || |krFqT|| 7}q*dS|o`|j| k}t|ƒr€|dkr€|  ¡r€| |_t| dƒsŽdS|  || ||¡} |   | ||||||¡S)ze Pass the event to the contained widget. May change focus on button 1 press. rcss|]\}}|VqdSrMr0rr0r0r1rr¬rYz#Pile.mouse_event..FrGr³) r:r”r-r,rrr£r3ràr<r³) r/rœr´rµr°r±r6rMr;r•rDr8rJr0r0r1r³¤s& ÿ   ÿzPile.mouse_event)N)N)F)F))r=r>r?r@rNr r rérer^rr*r)r·rr1r0r5r…rˆr,rêrr€r‘r“r6rr—rŽr3r¶r<r:r¬r­rªr¦r9r¯r³r0r0r0r1r ÌsF  =   ÿ   6  1 r c@s eZdZdS)Ú ColumnsErrorNrKr0r0r0r1rNÁsrNc@s†eZdZdZeeegƒZdIdd„Zdd„Z d d „Z d d „Z d d„Z e e e dd�Zdd„Zdd„Ze eedd�Zdd„Zdd„Ze eedd�Zdd„Zdd„Ze eedd�Zd d!„Zd"d#„Ze eed$d�Zeedd%fd&d'„ƒZd(d)„Zd*d+„Zd,d-„Z d.d/„Z!d0d1„Z"e e"d2d�Z#d3d4„Z$d5d6„Z%e e$e%d7d�Z&e e$e%d8d�Z'dJd9d:„Z(dKd;d<„Z)d=d>„Z*d?d@„Z+dAdB„Z,dCdD„Z-dLdEdF„Z.dGdH„Z/dS)Mr¡zE Widgets arranged horizontally in columns from left to right rNrGc s¼dˆ_ˆj ¡tƒˆ_ˆj ˆj¡ˆj ‡fdd„¡ˆj ˆj ¡t |pPdƒ}t |ƒD�](\}}|}t |t ƒs�ˆj |td||vff¡nâ|dttfvrÈt} |\} }ˆj || d||vff¡nªt|ƒdkrø|\} }ˆj |t| ||vff¡nz|dtk�r0t} |\} } }ˆj |t| ||vff¡nB|dtk�rd|\} } }ˆj || | ||vff¡ntd |fƒ‚|dur\| ¡r\|}q\|ˆ_ˆj�r¦|du�r¦|ˆ_dˆ_|ˆ_dˆ_dS) aX :param widget_list: iterable of flow or box widgets :param dividechars: number of blank characters between columns :param focus_column: index into widget_list of column in focus, if ``None`` the first selectable widget will be chosen. :param min_width: minimum width for each column which is not calling widget.pack() in *widget_list*. :param box_columns: a list of column indexes containing box widgets whose height is set to the maximum of the rows required by columns not listed in *box_columns*. *widget_list* may also contain tuples such as: (*given_width*, *widget*) make this column *given_width* screen columns wide, where *given_width* is an int (``'pack'``, *widget*) call :meth:`pack() ` to calculate the width of this column (``'weight'``, *weight*, *widget*) give this column a relative *weight* (number) to calculate its width from the screen columns remaining Widgets not in a tuple are the same as (``'weight'``, ``1``, *widget*) If the Columns widget is treated as a box widget then all children are treated as box widgets, and *box_columns* is ignored. If the Columns widget is treated as a flow widget then the rows are calculated as the largest rows() returned from all columns except the ones listed in *box_columns*. The box widgets in *box_columns* will be displayed with this calculated number of rows, filling the full height. Fcsˆ ¡SrMrTrVrEr0r1rXòrYz"Columns.__init__..r0rGrNrÏz$initial widget list item invalid: %r)rèÚ_Columns__superrer%rZr[r^r\r]rÚsetr”rŒrËr,r5rr r rDrr rNr£Ú dividecharsr3rrÀrc) r/rrQZ focus_columnrÀÚ box_columnsr•r r8rWZ_ignoredr‚r0rEr1reËsH#      ÿzColumns.__init__cCs"tdd„|jDƒƒ|_| ¡dS)r"css|]\}}| ¡VqdSrMr#r$r0r0r1rrrYz-Columns._contents_modified..Nr&rEr0r0r1r^szColumns._contents_modifiedc CsX|D]N}z$|\}\}}}|tttfvr*t‚WqttfyPtd|fƒ‚Yq0qdSrh)r rrrirjrN)r/rlrmrnr8rorpÚbr0r0r1rsz#Columns._validate_contents_modifiedcs0tdd„ˆjDƒƒ‰‡‡fdd„}ˆ |¡ˆS)Ncss|]\}}|VqdSrMr0rqr0r0r1rr)rYz+Columns._get_widget_list..csˆ ˆ¡dSrMr(r0rtr0r1rv*sz/Columns._get_widget_list..user_modifiedrwrxr0rtr1r*(s zColumns._get_widget_listc CsH|j}dd„t|t|jtdtddffƒƒƒDƒ|_|t|ƒkrD||_dS)NcSsg|]\}\}}||f‘qSr0r0r+r0r0r1rS0sz,Columns._set_widget_list..rGFr,r{r0r0r1r).sþÿ zColumns._set_widget_listz½ A list of the widgets in this Columns .. note:: only for backwards compatibility. You should use the new standard container property :attr:`contents`. r|cs0tdd„ˆjDƒƒ‰‡‡fdd„}ˆ |¡ˆS)Ncss0|](\}\}}}tttti ||¡|fVqdSrMr.©rQr8rorprSr0r0r1rr>s ÿz,Columns._get_column_types..csˆ ˆ¡dSrM)Ú_set_column_typesr0rtr0r1rvBsz0Columns._get_column_types..user_modifiedrwrxr0rtr1Ú_get_column_types=s ý zColumns._get_column_typescCs4|j}dd„t||jƒDƒ|_|t|ƒkr0||_dS)NcSs<g|]4\\}}\}\}}}|tttti ||¡||ff‘qSr0r2)rQr3Znew_nr8rorprSr0r0r1rSHsÿz-Columns._set_column_types..r4)r/Ú column_typesr3r0r0r1rUFs  ý zColumns._set_column_typeszÝ A list of the old partial options values for widgets in this Pile, for backwards compatibility only. You should use the new standard container property .contents to modify Pile contents. cs4tdd„tˆjƒDƒƒ‰‡‡fdd„}ˆ |¡ˆS)Ncss$|]\}\}\}}}|r|VqdSrMr0©rQr•r8rorprSr0r0r1rrUsz+Columns._get_box_columns..csˆ ˆ¡dSrM)Ú_set_box_columnsr0rtr0r1rvWsz/Columns._get_box_columns..user_modified)r$r”r,r[rxr0rtr1Ú_get_box_columnsTs ÿ zColumns._get_box_columnscs&tˆƒ‰‡fdd„t|jƒDƒ|_dS)Ncs,g|]$\}\}\}}}||||ˆvff‘qSr0r0rX©rRr0r1rS]sÿz,Columns._set_box_columns..)rPr”r,)r/rRr0r[r1rY[s þzColumns._set_box_columnsa A list of the indexes of the columns that are to be treated as box widgets when the Columns is treated as a flow widget. .. note:: only for backwards compatibility. You should use the new standard container property :attr:`contents`. cCsddl}| dt¡t|jvS©NrzA.has_flow_type is deprecated, read values from .contents instead.)ÚwarningsÚwarnÚDeprecationWarningr rW)r/r]r0r0r1Ú_get_has_pack_typehs ÿzColumns._get_has_pack_typecCsddl}| dt¡dSr\)r]r^r_)r/rÝr]r0r0r1Ú_set_has_pack_typemsÿzColumns._set_has_pack_typezP .. deprecated:: 1.0 Read values from :attr:`contents` instead. cCs|jSrMr„rEr0r0r1r…uszColumns._get_contentscCs||jdd…<dSrMr„r†r0r0r1rˆwszColumns._set_contentsa The contents of this Columns as a list of `(widget, options)` tuples. This list may be modified like a normal list and the Columns widget will update automatically. .. seealso:: Create new options tuples with the :meth:`options` method FcCs2|tkr d}|tttfvr(td|fƒ‚|||fS)a¨ Return a new options tuple for use in a Pile's .contents list. This sets an entry's width type: one of the following: ``'pack'`` Call the widget's :meth:`Widget.pack` method to determine how wide this column should be. *width_amount* is ignored. ``'given'`` Make column exactly width_amount screen-columns wide. ``'weight'`` Allocate the remaining space to this column by using *width_amount* as a weight value. :param width_type: ``'pack'``, ``'given'`` or ``'weight'`` :param width_amount: ``None`` for ``'pack'``, a number of screen columns for ``'given'`` or a weight value (number) for ``'weight'`` :param box_widget: set to `True` if this widget is to be treated as a box widget when the Columns widget itself is treated as a flow widget. :type box_widget: bool Nr‰)r rrrN)rŠr‹Z box_widgetr0r0r1r€�s zColumns.optionscCsd|_|j ¡dSrM)rcrOrUrEr0r0r1rUžszColumns._invalidatecCs| |¡dS)a4 Set the column in focus by its index in :attr:`widget_list`. :param num: index of focus-to-be entry :type num: int .. note:: only for backwards compatibility. You may also use the new standard container property :attr:`focus_position` to set the focus. N)rŽ)r/Znumr0r0r1Úset_focus_column¢s zColumns.set_focus_columncCs|jS)zÏ Return the focus column index. .. note:: only for backwards compatibility. You may also use the new standard container property :attr:`focus_position` to get the focus. )r3rEr0r0r1Úget_focus_column®szColumns.get_focus_columncCsRt|tƒr| |¡St|jƒD] \}\}}||kr||_dSqtd|fƒ‚dS)zë Set the item in focus .. note:: only for backwards compatibility. You may also use the new standard container property :attr:`focus_position` to get the focus. :param item: widget or integer indexNz(Widget not found in Columns contents: %rr6r7r0r0r1r‘·s  zColumns.set_focuscCs|js dS|j|jdSr8r’rEr0r0r1r“ÇszColumns.get_focusz7the child widget in focus or None when Columns is emptycCs|jstdƒ‚|jjS)zc Return the index of the widget in focus or None if this Columns is empty. z#No focus_position, Columns is empty)rr4r,r6rEr0r0r1r—ÓszColumns._get_focus_positionc CsPz|dks|t|jƒkrt‚Wn$ttfyBtd|fƒ‚Yn0||j_dS)r˜rz&No Columns child widget at position %sNr™r.r0r0r1rŽÛs zColumns._set_focus_positionz’ index of child widget in focus. Raises :exc:`IndexError` if read when Columns is empty, or when set to an invalid index. zý A property for reading and setting the index of the column in focus. .. note:: only for backwards compatibility. You may also use the new standard container property :attr:`focus_position` to get the focus. cCsÈ|d}||jkr,tdd„|jDƒƒs,|jSg}g}||j}t|jƒD]š\}\}\} } } | tkrh| } n,| tkrŽ| |f|o„||j k¡d} n|j } || |jkr°||j kr°qä|  | ¡|| |j8}| ttfvrH|  | |f¡qHt|ƒD]L\}}|dk�r�q:||||j7}d||<|rì|dd|krì|d=qì|�r¸|  ¡t dd„|Dƒƒ} |t|ƒ|j }|D]F\}}tt|ƒ|| dƒ} t|j | ƒ} | ||<|| 8}| |8} �qp||_||_|S)zy Return a list of column widths. 0 values in the list mean hide corresponding column completely rcss |]\}\}}}|tkVqdSrM)r rTr0r0r1rrýsz(Columns.column_widths..rGcss|]\}}|VqdSrMr0)rQÚweightr•r0r0r1rr$rYr=)rcr'r,Z_cache_column_widthsrQr”rr rãr3rÀr5Úsortr¤rDr�r>r)r/rœr6r�ÚwidthsZweightedZsharedr•r8ror‚rSZstatic_wr@Zgrowrdr0r0r1Ú column_widthsôsPÿ       zColumns.column_widthscCsr| ||¡}d}t|ƒdkrrd}tt||jƒƒD]@\}\}\}\}} } | rLq0|j|f|o`|j|kd�} t|| ƒ}q0g} tt||jƒƒD]Ž\}\}\}\}} } |dkr¦q†|r¸| r¸||f} n|f|dd…} |j| |oÜ|j|kd�}|t|ƒdkrü||j 7}|   |||j|k|f¡q†| �s.) r,r3r£ràrgrDr­rªr¤) r/rœr8rorprSrfZcolwrržrâr0rEr1r­`s&    ÿ zColumns.get_cursor_coordscCs”| |¡}d}d}tt||jƒƒD]¦\}\}\} } ||} |  ¡r¾|tkrt|tksZ||krt|durt||| | | f}qÊ|tkrœ||krœ||d||krœqÊ||| | | f}|tkr¾|| kr¾qÊ| |j}q"|durÖdS|\}}} } \} } }t| dƒ�r„t |t ƒ�r t t d||ƒ| |dƒ}n|}t |ƒdk�rV|�rV|  | || |¡f||¡}n |  | |f|dd…||¡}|du�r„dS||_||_dS)z… Choose a selectable column to focus based on the coords. see :meth:`Widget.move_cursor_coords` for details NrrÏFr¯rGT)rgr”r-r,r£rrrQràrŒr�rærrDr¯rªr3r)r/rœr°r±rfZbestržr•r‚r8r€ÚendrorprSZmove_xr²r0r0r1r¯ysD   $   ÿÿ zColumns.move_cursor_to_coordsc Cs| |¡}d}tt||jƒƒD]ì\} \} \} \} } }||krBdS|j| } || }||krh||j}q|ot|j| k}t|ƒr”|dkr”|  ¡r”| |_ t | dƒs¤dSt |ƒdkrÞ|rÞ|   |||  |¡f||||||¡S|   ||f|dd…||||||¡SdS)z_ Send event to appropriate column. May change focus on button 1 press. rFrGr³N)rgr”r-r,rrQÚ focus_colrr£r3ràrDr³rª)r/rœr´rµr°r±r6rfržr•r‚r8rorprSrir0r0r1r³¨s0 &    ÿ ÿzColumns.mouse_eventc Cs | |¡}|j|j\}\}}}t|ƒ|jkr2dSd}||j}t|dƒr¸t|ƒdkrp|rp| || |¡f¡}n| |f|dd…¡}t|tƒr¸||j |j 7}|t |d|j…ƒ7}|durÆ|j }|du�r|  ¡�r|d}||j|j 7}|t |d|j…ƒ7}|S)z-Return the pref col from the column in focus.rNr¶rGrÏ)rgr,r3rDràr¶rªrŒr�rjrQr¤rr£) r/rœrfr8rorprSr°Zcwidthr0r0r1r¶És(    zColumns.get_pref_colc Csb| ||¡}d}tt||jƒƒD]<\}\}\}\}} } | rr?r@rNr r rérer^rr*r)r·rrVrUrWrZrYrRr`raZ has_flow_typer…rˆr,rêrr€rUrbrcr‘r“r6r—rŽr3rjrgr¬r­r¯r³r¶rªr¦r0r0r0r1r¡ÅsX ÿ L     ÿ  = //! r¡cCsddl}| ¡dS)Nr)ÚdoctestZtestmod)rlr0r0r1Ú_test" srmÚ__main__N)AZ __future__rrÚ itertoolsrrZ urwid.compatrZ urwid.utilrZ urwid.widgetrr r r r r rrrrrrrrrrZurwid.decorationrrrrrrrrr r!r"r#Zurwid.monitored_listr$r%Z urwid.canvasr&r'r(r)r*rØr+rAÚ ExceptionrJrLr¸r¹rërìrr rNr¡rmr=r0r0r0r1ÚsH  H8F>mxa