@@ -3,14 +3,18 @@ use ratatui::{
3
3
style:: { palette:: tailwind, Style } ,
4
4
widgets:: {
5
5
block:: { Block , Padding , Position , Title } ,
6
- HighlightSpacing , List , ListDirection , ListItem , ListState , Paragraph , StatefulWidgetRef ,
6
+ Borders , List , ListDirection , ListItem , ListState , Paragraph ,
7
+ StatefulWidgetRef , Wrap ,
7
8
} ,
8
9
} ;
9
10
use strum:: { Display , EnumIter , FromRepr , IntoEnumIterator } ;
10
11
use throbber_widgets_tui:: { Throbber , ThrobberState } ;
12
+ use tui_widget_list:: PreRender ;
11
13
12
14
use crate :: dependency_builder:: CrateToAdd ;
13
15
16
+ use self :: style:: Stylize ;
17
+
14
18
#[ derive( Debug , Default , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
15
19
pub enum ItemListStatus {
16
20
Selected ,
@@ -117,7 +121,14 @@ impl From<FeatureItemList> for ListItem<'_> {
117
121
ItemListStatus :: Unselected => ( "☐" , Color :: default ( ) ) ,
118
122
} ;
119
123
120
- let line = Line :: from ( vec ! [ value. name. into( ) , " " . into( ) , is_selected. into( ) ] ) ;
124
+ let line = match value. status {
125
+ ItemListStatus :: Selected => {
126
+ Line :: from ( vec ! [ value. name. black( ) , " " . into( ) , is_selected. black( ) ] )
127
+ }
128
+ ItemListStatus :: Unselected => {
129
+ Line :: from ( vec ! [ value. name. into( ) , " " . into( ) , is_selected. into( ) ] )
130
+ }
131
+ } ;
121
132
122
133
ListItem :: new ( line) . style ( Style :: default ( ) . bg ( bg_color) )
123
134
}
@@ -169,7 +180,6 @@ impl StatefulWidgetRef for FeaturesWidgetList {
169
180
match & self . features {
170
181
Some ( features) => {
171
182
let features_list = List :: new ( features. clone ( ) )
172
- . highlight_style ( Style :: default ( ) . blue ( ) )
173
183
. highlight_symbol ( ">> " )
174
184
. direction ( ListDirection :: TopToBottom ) ;
175
185
@@ -212,9 +222,52 @@ pub struct CrateItemList {
212
222
pub description : String ,
213
223
pub features : Option < Vec < FeatureItemList > > ,
214
224
pub status : ItemListStatus ,
225
+ pub highlight_style : String ,
215
226
pub is_loading : bool ,
216
227
}
217
228
229
+ impl ratatui:: widgets:: Widget for CrateItemList {
230
+ fn render ( self , area : Rect , buf : & mut Buffer )
231
+ where
232
+ Self : Sized ,
233
+ {
234
+ let layout = Layout :: default ( )
235
+ . direction ( Direction :: Horizontal )
236
+ . constraints ( [ Constraint :: Fill ( 1 ) , Constraint :: Fill ( 4 ) ] ) ;
237
+
238
+ let [ name_area, description_area] = layout. areas ( area) ;
239
+
240
+ let ( is_selected, bg_color) = match self . status {
241
+ ItemListStatus :: Selected => ( "✓" , tailwind:: BLUE . c300 ) ,
242
+ ItemListStatus :: Unselected => ( "☐" , Color :: default ( ) ) ,
243
+ } ;
244
+
245
+ let name = format ! ( "{} {} {}" , self . highlight_style, self . name, is_selected) ;
246
+
247
+ name. bold ( ) . blue ( ) . render ( name_area, buf) ;
248
+
249
+ let description = match self . status {
250
+ ItemListStatus :: Unselected => self . description . into ( ) ,
251
+ ItemListStatus :: Selected => self . description . black ( ) ,
252
+ } ;
253
+
254
+ Paragraph :: new ( description)
255
+ . block ( Block :: default ( ) . borders ( Borders :: BOTTOM ) )
256
+ . style ( Style :: new ( ) . bg ( bg_color) )
257
+ . wrap ( Wrap { trim : true } )
258
+ . render ( description_area, buf) ;
259
+ }
260
+ }
261
+
262
+ impl PreRender for CrateItemList {
263
+ fn pre_render ( & mut self , context : & tui_widget_list:: PreRenderContext ) -> u16 {
264
+ if context. is_selected {
265
+ self . highlight_style = ">>" . to_string ( ) ;
266
+ }
267
+ 4
268
+ }
269
+ }
270
+
218
271
#[ derive( Clone , Default ) ]
219
272
pub struct CratesToAddListWidget {
220
273
pub crates : Vec < CrateToAdd > ,
@@ -263,6 +316,7 @@ impl CrateItemList {
263
316
features,
264
317
status,
265
318
is_loading : true ,
319
+ highlight_style : String :: default ( ) ,
266
320
}
267
321
}
268
322
}
@@ -292,16 +346,9 @@ impl From<CrateItemList> for ListItem<'_> {
292
346
}
293
347
294
348
impl StatefulWidgetRef for CratesListWidget {
295
- type State = ListState ;
349
+ type State = tui_widget_list :: ListState ;
296
350
fn render_ref ( & self , area : Rect , buf : & mut Buffer , state : & mut Self :: State ) {
297
- let block = Block :: default ( ) . padding ( Padding :: uniform ( 1 ) ) ;
298
-
299
- let list = List :: new ( self . crates . clone ( ) )
300
- . block ( block)
301
- . highlight_style ( Style :: default ( ) )
302
- . highlight_symbol ( ">> " )
303
- . highlight_spacing ( HighlightSpacing :: Always )
304
- . direction ( ListDirection :: TopToBottom ) ;
351
+ let list = tui_widget_list:: List :: new ( self . crates . clone ( ) ) ;
305
352
306
353
StatefulWidget :: render ( list, area, buf, state) ;
307
354
}
@@ -333,7 +380,9 @@ impl<'a> Widget for FooterInstructions<'a> {
333
380
{
334
381
let instructions = Title :: from ( Line :: from ( self . instructions ) ) ;
335
382
336
- let info = Title :: from ( Line :: from ( vec ! [ "V0.2.0" . into( ) ] ) )
383
+ let curret_version = format ! ( "V{}" , env!( "CARGO_PKG_VERSION" ) ) ;
384
+
385
+ let info = Title :: from ( Line :: from ( vec ! [ curret_version. into( ) ] ) )
337
386
. position ( Position :: Top )
338
387
. alignment ( Alignment :: Right ) ;
339
388
0 commit comments