@@ -694,24 +694,41 @@ class _DialogList(Generic[_T]):
694
694
Common code for `RadioList` and `CheckboxList`.
695
695
"""
696
696
697
- open_character : str = ""
698
- close_character : str = ""
699
- container_style : str = ""
700
- default_style : str = ""
701
- selected_style : str = ""
702
- checked_style : str = ""
703
- multiple_selection : bool = False
704
- show_scrollbar : bool = True
705
-
706
697
def __init__ (
707
698
self ,
708
699
values : Sequence [tuple [_T , AnyFormattedText ]],
709
700
default_values : Sequence [_T ] | None = None ,
701
+ select_on_focus : bool = False ,
702
+ open_character : str = "" ,
703
+ select_character : str = "*" ,
704
+ close_character : str = "" ,
705
+ container_style : str = "" ,
706
+ default_style : str = "" ,
707
+ number_style : str = "" ,
708
+ selected_style : str = "" ,
709
+ checked_style : str = "" ,
710
+ multiple_selection : bool = False ,
711
+ show_scrollbar : bool = True ,
712
+ show_cursor : bool = True ,
713
+ show_numbers : bool = False ,
710
714
) -> None :
711
715
assert len (values ) > 0
712
716
default_values = default_values or []
713
717
714
718
self .values = values
719
+ self .show_numbers = show_numbers
720
+
721
+ self .open_character = open_character
722
+ self .select_character = select_character
723
+ self .close_character = close_character
724
+ self .container_style = container_style
725
+ self .default_style = default_style
726
+ self .number_style = number_style
727
+ self .selected_style = selected_style
728
+ self .checked_style = checked_style
729
+ self .multiple_selection = multiple_selection
730
+ self .show_scrollbar = show_scrollbar
731
+
715
732
# current_values will be used in multiple_selection,
716
733
# current_value will be used otherwise.
717
734
keys : list [_T ] = [value for (value , _ ) in values ]
@@ -734,12 +751,18 @@ def __init__(
734
751
kb = KeyBindings ()
735
752
736
753
@kb .add ("up" )
754
+ @kb .add ("k" ) # Vi-like.
737
755
def _up (event : E ) -> None :
738
756
self ._selected_index = max (0 , self ._selected_index - 1 )
757
+ if select_on_focus :
758
+ self ._handle_enter ()
739
759
740
760
@kb .add ("down" )
761
+ @kb .add ("j" ) # Vi-like.
741
762
def _down (event : E ) -> None :
742
763
self ._selected_index = min (len (self .values ) - 1 , self ._selected_index + 1 )
764
+ if select_on_focus :
765
+ self ._handle_enter ()
743
766
744
767
@kb .add ("pageup" )
745
768
def _pageup (event : E ) -> None :
@@ -774,9 +797,22 @@ def _find(event: E) -> None:
774
797
self ._selected_index = self .values .index (value )
775
798
return
776
799
800
+ numbers_visible = Condition (lambda : self .show_numbers )
801
+
802
+ for i in range (1 , 10 ):
803
+
804
+ @kb .add (str (i ), filter = numbers_visible )
805
+ def _select_i (event : E , index : int = i ) -> None :
806
+ self ._selected_index = min (len (self .values ) - 1 , index - 1 )
807
+ if select_on_focus :
808
+ self ._handle_enter ()
809
+
777
810
# Control and window.
778
811
self .control = FormattedTextControl (
779
- self ._get_text_fragments , key_bindings = kb , focusable = True
812
+ self ._get_text_fragments ,
813
+ key_bindings = kb ,
814
+ focusable = True ,
815
+ show_cursor = show_cursor ,
780
816
)
781
817
782
818
self .window = Window (
@@ -831,13 +867,19 @@ def mouse_handler(mouse_event: MouseEvent) -> None:
831
867
result .append (("[SetCursorPosition]" , "" ))
832
868
833
869
if checked :
834
- result .append ((style , "*" ))
870
+ result .append ((style , self . select_character ))
835
871
else :
836
872
result .append ((style , " " ))
837
873
838
874
result .append ((style , self .close_character ))
839
- result .append ((self .default_style , " " ))
840
- result .extend (to_formatted_text (value [1 ], style = self .default_style ))
875
+ result .append ((f"{ style } { self .default_style } " , " " ))
876
+
877
+ if self .show_numbers :
878
+ result .append ((f"{ style } { self .number_style } " , f"{ i + 1 :2d} . " ))
879
+
880
+ result .extend (
881
+ to_formatted_text (value [1 ], style = f"{ style } { self .default_style } " )
882
+ )
841
883
result .append (("" , "\n " ))
842
884
843
885
# Add mouse handler to all fragments.
@@ -858,25 +900,44 @@ class RadioList(_DialogList[_T]):
858
900
:param values: List of (value, label) tuples.
859
901
"""
860
902
861
- open_character = "("
862
- close_character = ")"
863
- container_style = "class:radio-list"
864
- default_style = "class:radio"
865
- selected_style = "class:radio-selected"
866
- checked_style = "class:radio-checked"
867
- multiple_selection = False
868
-
869
903
def __init__ (
870
904
self ,
871
905
values : Sequence [tuple [_T , AnyFormattedText ]],
872
906
default : _T | None = None ,
907
+ show_numbers : bool = False ,
908
+ select_on_focus : bool = False ,
909
+ open_character : str = "(" ,
910
+ select_character : str = "*" ,
911
+ close_character : str = ")" ,
912
+ container_style : str = "class:radio-list" ,
913
+ default_style : str = "class:radio" ,
914
+ selected_style : str = "class:radio-selected" ,
915
+ checked_style : str = "class:radio-checked" ,
916
+ number_style : str = "class:radio-number" ,
917
+ multiple_selection : bool = False ,
918
+ show_cursor : bool = True ,
873
919
) -> None :
874
920
if default is None :
875
921
default_values = None
876
922
else :
877
923
default_values = [default ]
878
924
879
- super ().__init__ (values , default_values = default_values )
925
+ super ().__init__ (
926
+ values ,
927
+ default_values = default_values ,
928
+ select_on_focus = select_on_focus ,
929
+ show_numbers = show_numbers ,
930
+ open_character = open_character ,
931
+ select_character = select_character ,
932
+ close_character = close_character ,
933
+ container_style = container_style ,
934
+ default_style = default_style ,
935
+ selected_style = selected_style ,
936
+ checked_style = checked_style ,
937
+ number_style = number_style ,
938
+ multiple_selection = False ,
939
+ show_cursor = show_cursor ,
940
+ )
880
941
881
942
882
943
class CheckboxList (_DialogList [_T ]):
@@ -886,13 +947,30 @@ class CheckboxList(_DialogList[_T]):
886
947
:param values: List of (value, label) tuples.
887
948
"""
888
949
889
- open_character = "["
890
- close_character = "]"
891
- container_style = "class:checkbox-list"
892
- default_style = "class:checkbox"
893
- selected_style = "class:checkbox-selected"
894
- checked_style = "class:checkbox-checked"
895
- multiple_selection = True
950
+ def __init__ (
951
+ self ,
952
+ values : Sequence [tuple [_T , AnyFormattedText ]],
953
+ default_values : Sequence [_T ] | None = None ,
954
+ open_character : str = "[" ,
955
+ select_character : str = "*" ,
956
+ close_character : str = "]" ,
957
+ container_style : str = "class:checkbox-list" ,
958
+ default_style : str = "class:checkbox" ,
959
+ selected_style : str = "class:checkbox-selected" ,
960
+ checked_style : str = "class:checkbox-checked" ,
961
+ ) -> None :
962
+ super ().__init__ (
963
+ values ,
964
+ default_values = default_values ,
965
+ open_character = open_character ,
966
+ select_character = select_character ,
967
+ close_character = close_character ,
968
+ container_style = container_style ,
969
+ default_style = default_style ,
970
+ selected_style = selected_style ,
971
+ checked_style = checked_style ,
972
+ multiple_selection = True ,
973
+ )
896
974
897
975
898
976
class Checkbox (CheckboxList [str ]):
0 commit comments