
    AHjF                        U d Z ddlmZ ddlmZ ddlmZmZmZ ddl	m
Z
 ddlmZ  G d de      Zed	   Zd
ed<   	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 ddZddZ	 	 	 	 	 	 	 	 ddZ	 d	 	 	 	 	 	 	 	 	 ddZy)a  
Utilities to move index-based selections backward/forward.

These utilities concern themselves with selections where not all options are available,
otherwise it would be enough to increment/decrement the index and use the operator `%`
to implement wrapping.
    )annotations)count)LiteralProtocolSequence)	TypeAlias)loop_from_indexc                      e Zd ZU dZded<   y)Disableablez1Non-widgets that have an enabled/disabled status.booldisabledN)__name__
__module____qualname____doc____annotations__     R/root/tools/cai/cai_env/lib/python3.12/site-packages/textual/_widget_navigation.pyr   r      s
    ;Nr   r   )   r   	Directionc                    || |z
  z  |z  S )u  Computes the distance going from `start` to `index` in the given direction.

    Starting at `start`, this is the number of steps you need to take in the given
    `direction` to reach `index`, assuming there is wrapping at 0 and `wrap_at`.
    This is also the smallest non-negative integer solution `d` to
    `(start + d * direction) % wrap_at == index`.

    The diagram below illustrates the computation of `d1 = distance(2, 8, 1, 10)` and
    `d2 = distance(2, 8, -1, 10)`:

    ```
    start ────────────────────┐
    index ────────┐           │
    indices   0 1 2 3 4 5 6 7 8 9
    d1        2 3 4           0 1
              > > >           > > (direction == 1)
    d2            6 5 4 3 2 1 0
                  < < < < < < <   (direction == -1)
    ```

    Args:
        index: The index that we want to reach.
        start: The starting point to consider when computing the distance.
        direction: The direction in which we want to compute the distance.
        wrap_at: Controls at what point wrapping around takes place.

    Returns:
        The computed distance.
    r   )indexstart	directionwrap_ats       r   get_directed_distancer   !   s    @ &00r   c                :    t        d t        |       D        d      S )zFind the first enabled candidate in a sequence of possibly-disabled objects.

    Args:
        candidates: The sequence of candidates to consider.

    Returns:
        The first enabled candidate or `None` if none were available.
    c              3  @   K   | ]  \  }}|j                   r|  y wNr   ).0r   	candidates      r   	<genexpr>z%find_first_enabled.<locals>.<genexpr>P   s     W#5)IDVDVWs   N)next	enumerate)
candidatess    r   find_first_enabledr)   D   s!     Wy'<W r   c                l    t        |       t        fdt        t        |       d      D        d      S )zFind the last enabled candidate in a sequence of possibly-disabled objects.

    Args:
        candidates: The sequence of candidates to consider.

    Returns:
        The last enabled candidate or `None` if none were available.
    c              3  F   K   | ]  \  }}|j                   s|z
    y wr!   r"   )r#   offset_from_endr$   total_candidatess      r   r%   z$find_last_enabled.<locals>.<genexpr>`   s+      	
*%% .	
s   !r   )r   N)lenr&   r'   reversed)r(   r-   s    @r   find_last_enabledr0   U   s;     :	
.78LTU.V	

 	 r   c                    || r|dk(  rt        |       S t        |       S yt        | ||d      D ]  \  }}|j                  r|c S  |S )as  Find the next enabled object if we're currently at the given anchor.

    The definition of "next" depends on the given direction and this function will wrap
    around the ends of the sequence of object candidates.

    Args:
        candidates: The sequence of object candidates to consider.
        anchor: The point of the sequence from which we'll start looking for the next
            enabled object.
        direction: The direction in which to traverse the candidates when looking for
            the next enabled candidate.

    Returns:
        The next enabled object. If none are available, return the anchor.
    Nr   T)wrap)r)   r0   r	   r   )r(   anchorr   r   r$   s        r   find_next_enabledr4   i   sm    * ~ > #:. 'z2
 +J	PTU y!!L Mr   c                    || r|dk(  rt        |       S t        |       S y|r|n||z   }t        ||      }|dk(  r| |d nt        | d|dz          }t	        ||      D ]  \  }}|j
                  r|c S  y)aj  Find the next enabled object starting from the given anchor (without wrapping).

    The meaning of "next" and "past" depend on the direction specified.

    Args:
        candidates: The sequence of object candidates to consider.
        anchor: The point of the sequence from which we'll start looking for the next
            enabled object.
        direction: The direction in which to traverse the candidates when looking for
            the next enabled candidate.
        with_anchor: Whether to consider the anchor or not.

    Returns:
        The next enabled object. If none are available, return None.
    Nr   )r)   r0   r   r/   zipr   )	r(   r3   r   with_anchorr   countervalid_candidatesidxr$   s	            r   find_next_enabled_no_wrapr;      s    , ~ > #:. 'z2
 !Fv	'9EE9%G'1n
56(:kPQ	;R2S  g'78 Y
 r   N)
r   intr   r<   r   r   r   r<   returnr<   )r(   Sequence[Disableable]r=   
int | None)r(   r>   r3   r?   r   r   r=   r?   )F)
r(   r>   r3   r?   r   r   r7   r   r=   r?   )r   
__future__r   	itertoolsr   typingr   r   r   typing_extensionsr   textual._loopr	   r   r   r   r   r)   r0   r4   r;   r   r   r   <module>rE      s    #  . . ' )(  u~	9 % 1 1 1'0 1;> 1 1F%"(!%!! ! 	!P 	)%)) ) 	)
 )r   