@@ -115,7 +115,102 @@ pub fn run_tui(engine: Engine, config: Config) -> Result<()> {
115115 Ok ( ( ) )
116116}
117117
118- fn draw_ui ( _frame : & mut ratatui:: Frame , _app : & App ) { }
118+ fn draw_ui ( frame : & mut ratatui:: Frame , app : & App ) {
119+ let area = frame. area ( ) ;
120+ let theme = & app. config . theme ;
121+
122+ let chrome_border = parse_color ( & theme. chrome . border ) ;
123+ let chrome_title = parse_color ( & theme. chrome . title ) ;
124+
125+ let border_type = match app. config . tui . borders {
126+ BorderStyle :: None => ratatui:: widgets:: BorderType :: Plain ,
127+ BorderStyle :: Plain => ratatui:: widgets:: BorderType :: Plain ,
128+ BorderStyle :: Rounded => ratatui:: widgets:: BorderType :: Rounded ,
129+ } ;
130+
131+ let chunks = Layout :: default ( )
132+ . direction ( Direction :: Vertical )
133+ . constraints ( [
134+ Constraint :: Length ( 3 ) ,
135+ Constraint :: Min ( 10 ) ,
136+ Constraint :: Length ( 3 ) ,
137+ ] )
138+ . split ( area) ;
139+
140+ draw_header ( frame, chunks[ 0 ] , app, chrome_border, chrome_title, border_type) ;
141+ draw_footer ( frame, chunks[ 2 ] , app, chrome_border, border_type) ;
142+ }
143+
144+ fn draw_header (
145+ frame : & mut ratatui:: Frame ,
146+ area : Rect ,
147+ app : & App ,
148+ border_color : ratatui:: style:: Color ,
149+ title_color : ratatui:: style:: Color ,
150+ border_type : ratatui:: widgets:: BorderType ,
151+ ) {
152+ let mut tabs: Vec < Span > = Vec :: new ( ) ;
153+ if let Some ( snapshot) = & app. snapshot {
154+ for ( i, ( name, _) ) in snapshot. modules . iter ( ) . enumerate ( ) {
155+ let module_color = module_fg_color ( & app. config , name) ;
156+ if i == app. selected_tab {
157+ tabs. push ( Span :: styled (
158+ format ! ( " [{}] " , name. to_uppercase( ) ) ,
159+ Style :: default ( )
160+ . fg ( module_color)
161+ . add_modifier ( Modifier :: BOLD | Modifier :: UNDERLINED ) ,
162+ ) ) ;
163+ } else {
164+ tabs. push ( Span :: styled (
165+ format ! ( " {} " , name. to_uppercase( ) ) ,
166+ Style :: default ( ) . fg ( module_color) ,
167+ ) ) ;
168+ }
169+ }
170+ }
171+
172+ let header = Paragraph :: new ( Line :: from ( tabs) ) . block (
173+ Block :: default ( )
174+ . borders ( Borders :: ALL )
175+ . border_type ( border_type)
176+ . border_style ( Style :: default ( ) . fg ( border_color) )
177+ . title ( Span :: styled (
178+ " gim " ,
179+ Style :: default ( )
180+ . fg ( title_color)
181+ . add_modifier ( Modifier :: BOLD ) ,
182+ ) ) ,
183+ ) ;
184+ frame. render_widget ( header, area) ;
185+ }
186+
187+ fn draw_footer (
188+ frame : & mut ratatui:: Frame ,
189+ area : Rect ,
190+ app : & App ,
191+ border_color : ratatui:: style:: Color ,
192+ border_type : ratatui:: widgets:: BorderType ,
193+ ) {
194+ if !app. config . tui . show_help {
195+ return ;
196+ }
197+
198+ let help = Paragraph :: new ( Line :: from ( vec ! [
199+ Span :: styled( "q" , Style :: default ( ) . add_modifier( Modifier :: BOLD ) ) ,
200+ Span :: raw( " quit " ) ,
201+ Span :: styled( "←/→" , Style :: default ( ) . add_modifier( Modifier :: BOLD ) ) ,
202+ Span :: raw( " switch tab " ) ,
203+ Span :: styled( "Tab" , Style :: default ( ) . add_modifier( Modifier :: BOLD ) ) ,
204+ Span :: raw( " next " ) ,
205+ ] ) )
206+ . block (
207+ Block :: default ( )
208+ . borders ( Borders :: ALL )
209+ . border_type ( border_type)
210+ . border_style ( Style :: default ( ) . fg ( border_color) ) ,
211+ ) ;
212+ frame. render_widget ( help, area) ;
213+ }
119214
120215fn module_theme < ' a > ( config : & ' a Config , name : & str ) -> & ' a ModuleTheme {
121216 match name {
0 commit comments