
    AHj\                       U d dl mZ d dlmZ d dlmZmZmZmZm	Z	m
Z
 d dlZd dlmZ d dlmZ d dlmZmZ d dlmZ d d	lmZmZ d d
lmZ d dlmZ d dlmZmZ d dl m!Z! d dl"m#Z# d dl$m%Z%m&Z& erd dl'm(Z( d dl)m*Z*  G d d      Z+ e+       Z, G d de-      Z. G d de-      Z/ G d de&      Z0 G d de      Z1 e	de      Z2	 dZ3de4d <   	  G d! d"ee2   ed#$      Z5y)%    )annotations)	dataclass)TYPE_CHECKINGGenericHashableIterableTypeVarUnionN)RenderableType)Text)eventson)Binding)
HorizontalVertical)	NoMatches)Message)reactivevar)Timer)Static)Option
OptionList)	TypeAlias)ComposeResultc                      e Zd ZdZddZy)NoSelectionzmUsed by the `Select` widget to flag the unselected state. See [`Select.BLANK`][textual.widgets.Select.BLANK].c                     y)NzSelect.BLANK selfs    O/root/tools/cai/cai_env/lib/python3.12/site-packages/textual/widgets/_select.py__repr__zNoSelection.__repr__   s        N)returnstr)__name__
__module____qualname____doc__r#   r   r$   r"   r   r      s
    wr$   r   c                      e Zd ZdZy)InvalidSelectValueErrorzNRaised when setting a [`Select`][textual.widgets.Select] to an unknown option.Nr'   r(   r)   r*   r   r$   r"   r,   r,   $   s    Xr$   r,   c                      e Zd ZdZy)EmptySelectErrorzXRaised when a [`Select`][textual.widgets.Select] has no options and `allow_blank=False`.Nr-   r   r$   r"   r/   r/   (   s    br$   r/   c                       e Zd ZdZdgZe G d de             Ze G d de             Zdd fdZ	ddZ
d fd	Zdd
ZdddZddZddZddZddZddZ	 	 	 	 ddZ xZS )SelectOverlayz,The 'pop-up' overlay for the Select control.)escapedismisszDismiss menuc                       e Zd ZU dZdZded<   y)SelectOverlay.Dismissz0Inform ancestor the overlay should be dismissed.Fbool
lost_focusN)r'   r(   r)   r*   r7   __annotations__r   r$   r"   Dismissr5   1   s    > 
D -r$   r9   c                      e Zd ZU dZded<   y)SelectOverlay.UpdateSelectionz*Inform ancestor the selection was changed.intoption_indexN)r'   r(   r)   r*   r8   r   r$   r"   UpdateSelectionr;   8   s    8-r$   r>   c                P    t         |           || _        	 d| _        	 d| _        y )N gffffff?)super__init___type_to_search_search_query_search_reset_delay)r!   type_to_search	__class__s     r"   rB   zSelectOverlay.__init__?   s/    -r"$U*- nr$   c                L     d fd}t          j                  |       _        y )Nc                     d _         y Nr@   )rD   r    s   r"   reset_queryz+SelectOverlay.on_mount.<locals>.reset_queryK   s    !#Dr$   )callbackr%   None)r   rE   _search_reset_timer)r!   rK   s   ` r"   on_mountzSelectOverlay.on_mountJ   s$    	$ $)$**[$
 r$   c                    d| _         |r| j                  j                          n4| j                  j                          | j                  j	                          t
        |   |       y rJ   )rD   rO   _startresetstoprA   watch_has_focus)r!   valuerG   s     r"   rU   zSelectOverlay.watch_has_focusR   sQ    $$++-$$**,$$))+&r$   c                x  K   | j                   sy | j                  j                          |j                  |j                  rvd|_        |j                          |j                          | xj                  |j                  z  c_        | j                  | j                        }|| j                  |       y y y y w)Nr   )rC   rO   rS   	characteris_printabletimerT   prevent_defaultrD   _find_search_matchselect)r!   eventindexs      r"   _on_keyzSelectOverlay._on_key[   s     ##  &&(??&5+=+=EJJJL!!# %//1++D,>,>?E E" ! ,>&s   B8B:c                J    | j                   xr |duxr |j                         S )z.Check if the widget may consume the given key.N)rC   isprintable)r!   keyrX   s      r"   check_consume_keyzSelectOverlay.check_consume_keyl   s*       VYd%:Vy?T?T?V	
r$   c                2    || _         | j                          y)zRMove selection.

        Args:
            index: Index of new selection.
        N)highlightedscroll_to_highlight)r!   r_   s     r"   r]   zSelectOverlay.selectr   s     !  "r$   c                `   d}d}|j                         }t        | j                        D ]  \  }}|j                  }t	        |t
              r|j                  j                         }n"t	        |t              r|j                         }n_|j                  |      }|dk7  sv|||k  s~|}|} |S )a  A simple substring search which favors options containing the substring
        earlier in the prompt.

        Args:
            query: The substring to search for.

        Returns:
            The index of the option that matches the query, or `None` if no match is found.
        N)	lower	enumerate_optionsprompt
isinstancer   plainr&   find)	r!   query
best_matchminimum_indexr_   optionrm   lower_promptmatch_indexs	            r"   r\   z SelectOverlay._find_search_match{   s     "&
$(&t}}5 	,ME6]]F&$'%||113FC(%||~&++E2Kb %})D"
 +	,  r$   c                B    | j                  | j                                y)Dismiss the overlay.N)post_messager9   r    s    r"   action_dismisszSelectOverlay.action_dismiss   s    $,,.)r$   c                f    | j                  | j                  d             | j                          y)z'On blur we want to dismiss the overlay.T)r7   N)ry   r9   suppress_clickr!   _events     r"   _on_blurzSelectOverlay._on_blur   s'    $,,$,78r$   c                x    |j                          | j                  | j                  |j                               y)z)Inform parent when an option is selected.N)rT   ry   r>   r=   r!   r^   s     r"   on_option_list_option_selectedz,SelectOverlay.on_option_list_option_selected   s*    

$..u/A/ABCr$   c                $    |j                          y)z.Stop option list highlighted messages leaking.N)rT   r   s     r"   !on_option_list_option_highlightedz/SelectOverlay.on_option_list_option_highlighted   s     	

r$   )T)rF   r6   r%   rN   rM   )rV   r6   r%   rN   )r^   z
events.Keyr%   rN   N)rc   r&   rX   
str | Noner%   r6   )r_   
int | Noner%   rN   )rq   r&   r%   r   )r~   zevents.Blurr%   rN   )r^   zOptionList.OptionSelectedr%   rN   )r^   zOptionList.OptionHighlightedr%   rN   )r'   r(   r)   r*   BINDINGSr   r   r9   r>   rB   rP   rU   r`   rd   r]   r\   rz   r   r   r   __classcell__rG   s   @r"   r1   r1   ,   s    656H.' . . .' . .	o
'#"
#@*
D
1	r$   r1   c                  |     e Zd ZU dZdZ ed      Zded<   	  G d de      Z	d fdZ
dd	Zdd
ZddZddZ xZS )SelectCurrentz'Displays the currently selected option.aT  
    SelectCurrent {
        border: tall $border-blurred;
        color: $foreground;
        background: $surface;
        width: 1fr;
        height: auto;
        padding: 0 2;

        &.-textual-compact {
            border: none !important;
        }

        &:ansi {
            border: tall ansi_blue;
            color: ansi_default;
            background: ansi_default;
        }

        Static#label {
            width: 1fr;
            height: auto;
            color: $foreground 50%;
            background: transparent;
        }

        &.-has-value Static#label {
            color: $foreground;
        }

        .arrow {
            box-sizing: content-box;
            width: 1;
            height: 1;
            padding: 0 0 0 1;
            color: $foreground 50%;
            background: transparent;
        }
    }
    F	var[bool]	has_valuec                      e Zd ZdZy)SelectCurrent.TogglezRequest toggle overlay.Nr-   r   r$   r"   Toggler      s    %r$   r   c                Z    t         |           || _        t        j                  | _        y)zInitialize the SelectCurrent.

        Args:
            placeholder: A string to display when there is nothing selected.
        N)rA   rB   placeholderSelectBLANKlabel)r!   r   rG   s     r"   rB   zSelectCurrent.__init__   s#     	&39<<
r$   c                    || _         |t        j                  u| _        | j	                  dt
              j                  t        |t              r| j                         y|       y)zUpdate the content in the widget.

        Args:
            label: A renderable to display, or `None` for the placeholder.
        z#labelN)
r   r   r   r   	query_oner   updatern   r   r   )r!   r   s     r"   r   zSelectCurrent.update   sN     
fll2x(// *5+ >D	
DI	
r$   c              #  z   K   t        | j                  d       t        dd       t        dd       yw)	zCompose label and down arrow.r   )idu   ▼zarrow down-arrow)classesu   ▲zarrow up-arrowN)r   r   r    s    r"   composezSelectCurrent.compose   s5     T%%'22U$677U$455s   9;c                (    | j                  |d       y)zToggle the class.z
-has-valueN)	set_class)r!   r   s     r"   _watch_has_valuezSelectCurrent._watch_has_value   s    y,/r$   c                b    |j                          | j                  | j                                y)z"Inform ancestor we want to toggle.N)rT   ry   r   r   s     r"   	_on_clickzSelectCurrent._on_click  s    

$++-(r$   )r   r&   r%   rN   )r   zRenderableType | NoSelectionr%   rN   r%   r   )r   r6   r%   rN   )r^   zevents.Clickr%   rN   )r'   r(   r)   r*   DEFAULT_CSSr   r   r8   r   r   rB   r   r   r   r   r   r   s   @r"   r   r      sG    1'KR u:Iy%C& &@

60)r$   r   
SelectType)boundztuple[str, SelectType]r   SelectOptionc                      e Zd ZU dZeZ	  edddd      gZ	 dZ edd      Z	d	e
d
<   	  ee   d       Zde
d<   	  eeeef      ed      Zde
d<   	  edd      Z	 ej(                  j*                   G d de             Zd dedddddddd
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d* fdZed deddddddd		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d+d       Zed,d       Z	 	 	 	 d-dZd.dZefd/dZd-dZ 	 	 	 	 d0dZ!d1dZ"d2d Z#d3d!Z$d4d"Z% e&e'jP                        d5d#       Z) e&e*jV                        d6d$       Z, e&e*jZ                        d7d%       Z.d.d&Z/d8d'Z0d.d(Z1d9d)Z2 xZ3S ):r   zWidget to select from a list of possible options.

    A Select displays the current selection.
    When activated with ++enter++ the widget displays an overlay with a list of all possible options.
    zenter,down,space,upshow_overlayz	Show menuF)showa  
    Select {
        height: auto;
        color: $foreground;

        &.-textual-compact {
            & > SelectCurrent {
                padding: 0 1 0 0;
                border: none !important;
            }            
        }
        
        .up-arrow {
            display: none;
        }

        &:focus > SelectCurrent {
            border: tall $border;
            background-tint: $foreground 5%;
        }

        & > SelectOverlay {
            width: 1fr;
            display: none;
            height: auto;
            max-height: 12;
            overlay: screen;
            constrain: none inside;
            color: $foreground;
            border: tall $border-blurred;
            background: $surface;
            &:focus {
                background-tint: $foreground 5%;
            }
            & > .option-list--option {
                padding: 0 1;
            }
        }

        &.-expanded {
            .down-arrow {
                display: none;
            }
            .up-arrow {
                display: block;
            }
            & > SelectOverlay {
                display: block;
            }
        }

    }

    )initr   expandedzvar[str]rm   zvar[SelectType | NoSelection]rV   z-textual-compact)toggle_classc                  J     e Zd ZdZ	 	 	 	 	 	 d fdZddZedd       Z xZS )Select.Changedz{Posted when the select value was changed.

        This message can be handled using a `on_select_changed` method.
        c                @    t         |           || _        	 || _        y)z9
            Initialize the Changed message.
            N)rA   rB   r]   rV   )r!   r]   rV   rG   s      r"   rB   zSelect.Changed.__init__p  s$     G DK$DJ:r$   c              #  D   K   | j                    | j                   y wr   )r]   rV   r    s    r"   __rich_repr__zSelect.Changed.__rich_repr__|  s     ++**s    c                    | j                   S )z!The Select that sent the message.)r]   r    s    r"   controlzSelect.Changed.control  s     ;;r$   )r]   Select[SelectType]rV   SelectType | NoSelectionr%   rN   )r%   zrich.repr.Result)r%   r   )	r'   r(   r)   r*   rB   r   propertyr   r   r   s   @r"   Changedr   i  s>    	

	;,
	;5M
	;
	;	 
	 
	r$   r   TN)
rm   allow_blankrV   rF   namer   r   disabledtooltipcompactc       
            t         |   ||||	       || _        || _        || _        | j                  |       || _        |
|
| _        || _        y)a  Initialize the Select control.

        Args:
            options: Options to select from. If no options are provided then
                `allow_blank` must be set to `True`.
            prompt: Text to show in the control when no option is selected.
            allow_blank: Enables or disables the ability to have the widget in a state
                with no selection made, in which case its value is set to the constant
                [`Select.BLANK`][textual.widgets.Select.BLANK].
            value: Initial value selected. Should be one of the values in `options`.
                If no initial value is set and `allow_blank` is `False`, the widget
                will auto-select the first available option.
            type_to_search: If `True`, typing will search for options.
            name: The name of the select control.
            id: The ID of the control in the DOM.
            classes: The CSS classes of the control.
            disabled: Whether the control is disabled or not.
            tooltip: Optional tooltip.
            compact: Enable compact select (without borders).

        Raises:
            EmptySelectError: If no options are provided and `allow_blank` is `False`.
        )r   r   r   r   N)	rA   rB   _allow_blankrm   _value_setup_variables_for_optionsrC   r   r   )r!   optionsrm   r   rV   rF   r   r   r   r   r   r   rG   s               r"   rB   zSelect.__init__  s\    L 	dr7XN'))'2-"DLr$   	rm   r   rV   rF   r   r   r   r   r   c       	        d    |D cg c]  }t        |      |f }} | ||||||||	|

      S c c}w )a  Initialize the Select control with values specified by an arbitrary iterable

        The options shown in the control are computed by calling the built-in `str`
        on each value.

        Args:
            values: Values used to generate options to select from.
            prompt: Text to show in the control when no option is selected.
            allow_blank: Enables or disables the ability to have the widget in a state
                with no selection made, in which case its value is set to the constant
                [`Select.BLANK`][textual.widgets.Select.BLANK].
            value: Initial value selected. Should be one of the values in `values`.
                If no initial value is set and `allow_blank` is `False`, the widget
                will auto-select the first available value.
            type_to_search: If `True`, typing will search for options.
            name: The name of the select control.
            id: The ID of the control in the DOM.
            classes: The CSS classes of the control.
            disabled: Whether the control is disabled or not.
            compact: Enable compact style?

        Returns:
            A new Select widget with the provided values as options.
        r   )r&   )clsvaluesrm   r   rV   rF   r   r   r   r   r   options_iterators               r"   from_valueszSelect.from_values  sT    N >DDESZ/DD#)
 	
 Es   -c                @    | j                   }t        |t              ry|S )zThe currently selected item.

        Unlike [value][textual.widgets.Select.value], this will not return Blanks.
        If nothing is selected, this will return `None`.

        N)rV   rn   r   )r!   rV   s     r"   	selectionzSelect.selection  s     

e[)r$   c                0   g | _         | j                  r'| j                   j                  d| j                  f       | j                   j	                  |       | j                   st        d      | j                   D ch c]  \  }}|	 c}}| _        yc c}}w )zSetup function for the auxiliary variables related to options.

        This method sets up `self._options` and `self._legal_values`.
        r@   z;Select options cannot be empty if selection can't be blank.N)rl   r   appendr   extendr/   _legal_values)r!   r   _rV   s       r"   r   z#Select._setup_variables_for_options  s     PRMM  "djj!12W%}}"M 
 #'--=
aE=
 =
s   <Bc           
     (   | j                   D cg c]?  \  }}|| j                  k(  r t        t        | j                  d            n
t        |      A }}}| j                  t              }|j                          |j                  |       yc c}}w )zFSets up the `Option` renderables associated with the `Select` options.dimstyleN)	rl   r   r   r   rm   r   r1   clear_optionsadd_options)r!   rm   rV   r   option_lists        r"   _setup_options_renderablesz!Select._setup_options_renderables  s     "&!
  DJJ& tDKKu56F^$!
 !
 nn]3!!#(!
s   ABc                l    || j                   k(  r| j                  s| j                  d   d   }|| _        y)z1Initialises the selected option for the `Select`.r      N)r   r   rl   rV   )r!   hints     r"   _init_selected_optionzSelect._init_selected_option  s0    4::d&7&7==#A&D
r$   c                f    | j                  |       | j                          | j                          y)a  Set the options for the Select.

        This will reset the selection. The selection will be empty, if allowed, otherwise
        the first valid option is picked.

        Args:
            options: An iterable of tuples containing the renderable to display for each
                option and the corresponding internal value.

        Raises:
            EmptySelectError: If the options iterable is empty and `allow_blank` is
                `False`.
        N)r   r   r   )r!   r   s     r"   set_optionszSelect.set_options#  s*     	))'2'')""$r$   c                R    || j                   vr|dnd}t        d|d|z         |S )a  Ensure the new value is a valid option.

        If `allow_blank` is `True`, `None` is also a valid value and corresponds to no
            selection.

        Raises:
            InvalidSelectValueError: If the new value does not correspond to any known
                value.
        z$ Did you mean to use Select.clear()?r@   zIllegal select value .)r   r,   )r!   rV   	help_texts      r"   _validate_valuezSelect._validate_value5  sH     *** CH->UWI)'y2Y>  r$   c                   || _         	 | j                  t              }|| j                  k(  r|j	                  | j                         nTt        | j                        D ]<  \  }\  }}||k(  s| j                  t              }||_        |j	                  |        n | j                  | j                  | |             y# t        $ r Y yw xY w)z)Update the current value when it changes.N)r   r   r   r   r   rk   rl   r1   rf   ry   r   r   )r!   rV   select_currentr_   rm   r   select_overlays          r"   _watch_valuezSelect._watch_valueL  s    	9!^^M:N 

"%%djj1/8/G +E+FF)-)F5:2&--f5 dll478  		s   B? ?	C
Cc              #     K   t        | j                         t        | j                        j	                  t
        j                         yw)z.Compose Select with overlay and current value.)rF   )r   N)r   rm   r1   rC   	data_bindr   r   r    s    r"   r   zSelect.compose_  s@     DKK((4+?+?@JJNN K 
 	
s   AAc                Z    | j                          | j                  | j                         y)zSet initial values.N)r   r   r   r}   s     r"   	_on_mountzSelect._on_mountf  s     '')""4;;/r$   c                   	 | j                  t              }| j                  |d       |r|j	                  d       | j
                  | j                  u r,|j                  d       d| j                  t              _	        y| j
                  }t        | j                        D ]   \  }\  }}||k(  s|j                  |        n d| j                  t              _	        yy# t        $ r Y yw xY w)zDisplay or hide overlay.Nz	-expandedF)scroll_visibleT)r   r1   r   r   focusrV   r   r]   r   r   rk   rl   )r!   r   overlayrV   r_   _promptprompt_values          r"   _watch_expandedzSelect._watch_expandedk  s    	nn]3G 	x-MMM/zzTZZ't$:?}-7

6?6N 2E2G\,u- ;?}-7 	  		s   C! !	C-,C-c                H    |j                          | j                   | _        y)zShow the overlay when toggled.N)rT   r   r   s     r"   _select_current_togglezSelect._select_current_toggle  s     	

 MM)r$   c                l    |j                          d| _        |j                  s| j                          yy)rx   FN)rT   r   r7   r   r   s     r"   _select_overlay_dismisszSelect._select_overlay_dismiss  s+     	

JJL  r$   c                    |j                          | j                  |j                     d   }|| j                  k7  r|| _        | j	                          d| _        y)zUpdate the current selection.r   FN)rT   rl   r=   rV   r   r   )r!   r^   rV   s      r"   _update_selectionzSelect._update_selection  sI     	

e001!4DJJDJ

r$   c                    | j                  t              }d|_        d| _        | j                  t              }|j
                  |j                          yy)zShow the overlay.TN)r   r   r   r   r1   rf   action_first)r!   r   r   s      r"   action_show_overlayzSelect.action_show_overlay  sJ    6#' 6%%-'') .r$   c                4    | j                   | j                  k(  S )zIndicates whether this `Select` is blank or not.

        Returns:
            True if the selection is blank, False otherwise.
        )rV   r   r    s    r"   is_blankzSelect.is_blank  s     zzTZZ''r$   c                Z    	 | j                   | _        y# t        $ r t        d      dw xY w)zClear the selection if `allow_blank` is `True`.

        Raises:
            InvalidSelectValueError: If `allow_blank` is set to `False`.
        z5Can't clear selection if allow_blank is set to False.N)r   rV   r,   r    s    r"   clearzSelect.clear  s4    	DJ& 	)G	s    *c                <   | j                   sy | j                  t              }||_        | j                  sy | j
                  | j                  k(  r|j                  | j                         | j                  t              }|j                  dt        |d             y )Nr   r   r   )
is_mountedr   r   r   r   rV   r   r   r1   replace_option_prompt_at_indexr   )r!   rm   r   r   s       r"   _watch_promptzSelect._watch_prompt  su    6%+"  ::#!!$**-nn]3221d66OPr$   )r   +Iterable[tuple[RenderableType, SelectType]]rm   r&   r   r6   rV   r   rF   r6   r   r   r   r   r   r   r   r6   r   zRenderableType | Noner   r6   )r   zIterable[SelectType]rm   r&   r   r6   rV   r   rF   r6   r   r   r   r   r   r   r   r6   r   r6   r%   r   )r%   zSelectType | None)r   r  r%   rN   rM   )r   r   r%   rN   )rV   r   r%   r   )rV   r   r%   rN   r   )r~   zevents.Mountr%   rN   )r   r6   r%   rN   )r^   r   r%   rN   )r^   r5   r%   rN   )r^   r;   r%   rN   )r%   r6   )rm   r&   r%   rN   )4r'   r(   r)   r*   r   r   r   r   r   r   r8   r&   rm   r
   r   r   rV   r   r   richreprautor   r   rB   classmethodr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r1   r9   r   r>   r   r   r   r   r  r   r   s   @r"   r   r     s    E< 	%~{OH5Kn e%0Hi04s3x)FH)7+N3uZ5L/M+NE,E(  u+=>G4	YY^^'  >  */#")-.<. 	.
 . (. . . . . . '. .` 
  */#"3
$3
 	3

 3
 (3
 3
 3
 3
 3
 3
 3
 
3
 3
j 
 

<
 

,) FK %$-	!.9&
0
?* * *
   %%& '*(
Qr$   r   T)	can_focus)6
__future__r   dataclassesr   typingr   r   r   r   r	   r
   	rich.reprr  rich.consoler   	rich.textr   textualr   r   textual.bindingr   textual.containersr   r   textual.css.queryr   textual.messager   textual.reactiver   r   textual.timerr   textual.widgetsr   textual.widgets._option_listr   r   typing_extensionsr   textual.appr   r   r   	Exceptionr,   r/   r1   r   r   r   r8   r   r   r$   r"   <module>r     s    " ! M M  '   # 3 ' # *  " ;+)  	Yi Ycy cAJ AHU)J U)p \2
 +2i 2 .uQWZ (d uQr$   