44from textual .containers import Horizontal , Vertical , VerticalScroll
55from textual .design import ColorSystem
66from textual .widget import Widget
7- from textual .widgets import Button , Footer , Label , Static , TabbedContent
7+ from textual .widgets import Footer , Label , OptionList , Static , TabbedContent
8+ from textual .widgets .option_list import Option
89
910try :
1011 from textual .lazy import Lazy
@@ -14,12 +15,6 @@ def Lazy(widget: Widget) -> Widget: # type: ignore
1415 return widget
1516
1617
17- class ThemeColorButtons (VerticalScroll ):
18- def compose (self ) -> ComposeResult :
19- for color_name in ColorSystem .COLOR_NAMES :
20- yield Button (color_name , id = color_name )
21-
22-
2318class ColorBar (Static ):
2419 pass
2520
@@ -56,7 +51,7 @@ def compose(self) -> ComposeResult:
5651 yield ColorBar (f"{ color .rgb } " , classes = "text text-left" )
5752
5853
59- class ThemeColorsView (ColorsView ):
54+ class ThemeColorsView (ColorsView , can_focus = False ):
6055 def compose (self ) -> ComposeResult :
6156 LEVELS = [
6257 "darken-3" ,
@@ -80,22 +75,59 @@ def compose(self) -> ComposeResult:
8075
8176
8277class ColorsApp (App [None ]):
83- CSS_PATH = "colors.css "
78+ CSS_PATH = "colors.tcss "
8479
85- BINDINGS = [("d" , "toggle_dark" , "Toggle dark mode" )]
80+ BINDINGS = [
81+ ("[" , "previous_theme" , "Previous theme" ),
82+ ("]" , "next_theme" , "Next theme" ),
83+ ]
84+
85+ def __init__ (self ) -> None :
86+ super ().__init__ ()
87+ self .theme_names = [
88+ theme for theme in self .available_themes if theme != "textual-ansi"
89+ ]
8690
8791 def compose (self ) -> ComposeResult :
8892 yield Footer ()
8993 with ColorTabs ("Theme Colors" , "Named Colors" ):
90- yield Content (ThemeColorButtons (), ThemeColorsView (), id = "theme" )
94+ with Content (id = "theme" ):
95+ sidebar = OptionList (
96+ * [
97+ Option (color_name , id = color_name )
98+ for color_name in ColorSystem .COLOR_NAMES
99+ ],
100+ id = "sidebar" ,
101+ )
102+ sidebar .border_title = "Theme Colors"
103+ yield sidebar
104+ yield ThemeColorsView ()
91105 yield Lazy (NamedColorsView ())
92106
93- def on_button_pressed (self , event : Button .Pressed ) -> None :
107+ def on_option_list_option_highlighted (
108+ self , event : OptionList .OptionHighlighted
109+ ) -> None :
94110 self .query (ColorGroup ).remove_class ("-active" )
95- group = self .query_one (f"#group-{ event .button .id } " , ColorGroup )
111+ group = self .query_one (f"#group-{ event .option .id } " , ColorGroup )
96112 group .add_class ("-active" )
97113 group .scroll_visible (top = True , speed = 150 )
98114
115+ def action_next_theme (self ) -> None :
116+ themes = self .theme_names
117+ index = themes .index (self .current_theme .name )
118+ self .theme = themes [(index + 1 ) % len (themes )]
119+ self .notify_new_theme (self .current_theme .name )
120+
121+ def action_previous_theme (self ) -> None :
122+ themes = self .theme_names
123+ index = themes .index (self .current_theme .name )
124+ self .theme = themes [(index - 1 ) % len (themes )]
125+ self .notify_new_theme (self .current_theme .name )
126+
127+ def notify_new_theme (self , theme_name : str ) -> None :
128+ self .clear_notifications ()
129+ self .notify (f"Theme is { theme_name } " )
130+
99131
100132if __name__ == "__main__" :
101133 ColorsApp ().run ()
0 commit comments