@@ -12,6 +12,7 @@ use crate::{
1212 render:: { Renderer , SharedRenderer } ,
1313 PaneFactory ,
1414 } ,
15+ preset:: Evaluator ,
1516 widgets:: {
1617 checkbox,
1718 text:: { self , Text } ,
@@ -28,16 +29,13 @@ pub enum Index {
2829 Checkbox = 1 ,
2930}
3031
31- /// Type alias for the evaluator function used in the checkbox preset.
32- pub type Evaluator = fn ( event : & Event , ctx : & mut Checkbox ) -> anyhow:: Result < Signal > ;
33-
3432/// Represents a checkbox component for creating
3533/// and managing a list of selectable options.
3634pub struct Checkbox {
3735 /// Shared renderer for the prompt, allowing for rendering of UI components.
3836 pub renderer : Option < SharedRenderer < Index > > ,
3937 /// Function to evaluate the input events and update the state of the prompt.
40- pub evaluator_fn : Evaluator ,
38+ pub evaluator : Evaluator < Self > ,
4139 /// State for the title displayed above the checkbox list.
4240 pub title : text:: State ,
4341 /// State for the checkbox list itself.
@@ -46,12 +44,6 @@ pub struct Checkbox {
4644
4745#[ async_trait:: async_trait]
4846impl crate :: Prompt for Checkbox {
49- type Index = Index ;
50-
51- fn renderer ( & self ) -> SharedRenderer < Self :: Index > {
52- self . renderer . clone ( ) . unwrap ( )
53- }
54-
5547 async fn initialize ( & mut self ) -> anyhow:: Result < ( ) > {
5648 let size = crossterm:: terminal:: size ( ) ?;
5749 self . renderer = Some ( SharedRenderer :: new (
@@ -68,17 +60,9 @@ impl crate::Prompt for Checkbox {
6860 }
6961
7062 async fn evaluate ( & mut self , event : & Event ) -> anyhow:: Result < Signal > {
71- let ret = ( self . evaluator_fn ) ( event, self ) ;
63+ let ret = ( self . evaluator ) ( event, self ) . await ;
7264 let size = crossterm:: terminal:: size ( ) ?;
73- self . renderer
74- . as_ref ( )
75- . unwrap ( )
76- . update ( [
77- ( Index :: Title , self . title . create_pane ( size. 0 , size. 1 ) ) ,
78- ( Index :: Checkbox , self . checkbox . create_pane ( size. 0 , size. 1 ) ) ,
79- ] )
80- . render ( )
81- . await ?;
65+ self . render ( size. 0 , size. 1 ) . await ?;
8266 ret
8367 }
8468
@@ -96,11 +80,10 @@ impl crate::Prompt for Checkbox {
9680}
9781
9882impl Checkbox {
99- /// Creates a new `Checkbox` instance with the provided items.
100- pub fn new < T : Display , I : IntoIterator < Item = T > > ( items : I ) -> Self {
83+ fn new_with_checkbox ( checkbox : checkbox:: Checkbox ) -> Self {
10184 Self {
10285 renderer : None ,
103- evaluator_fn : evaluate:: default,
86+ evaluator : |event , ctx| Box :: pin ( evaluate:: default ( event , ctx ) ) ,
10487 title : text:: State {
10588 style : ContentStyle {
10689 attributes : Attributes :: from ( Attribute :: Bold ) ,
@@ -109,7 +92,7 @@ impl Checkbox {
10992 ..Default :: default ( )
11093 } ,
11194 checkbox : checkbox:: State {
112- checkbox : checkbox :: Checkbox :: from_displayable ( items ) ,
95+ checkbox,
11396 cursor : String :: from ( "❯ " ) ,
11497 active_mark : '☒' ,
11598 inactive_mark : '☐' ,
@@ -123,31 +106,14 @@ impl Checkbox {
123106 }
124107 }
125108
109+ /// Creates a new `Checkbox` instance with the provided items.
110+ pub fn new < T : Display , I : IntoIterator < Item = T > > ( items : I ) -> Self {
111+ Self :: new_with_checkbox ( checkbox:: Checkbox :: from_displayable ( items) )
112+ }
113+
126114 /// Creates a new `Checkbox` instance with the provided items and their checked states.
127115 pub fn new_with_checked < T : Display , I : IntoIterator < Item = ( T , bool ) > > ( items : I ) -> Self {
128- Self {
129- renderer : None ,
130- evaluator_fn : evaluate:: default,
131- title : text:: State {
132- style : ContentStyle {
133- attributes : Attributes :: from ( Attribute :: Bold ) ,
134- ..Default :: default ( )
135- } ,
136- ..Default :: default ( )
137- } ,
138- checkbox : checkbox:: State {
139- checkbox : checkbox:: Checkbox :: new_with_checked ( items) ,
140- cursor : String :: from ( "❯ " ) ,
141- active_mark : '☒' ,
142- inactive_mark : '☐' ,
143- active_item_style : ContentStyle {
144- foreground_color : Some ( Color :: DarkCyan ) ,
145- ..Default :: default ( )
146- } ,
147- inactive_item_style : ContentStyle :: default ( ) ,
148- lines : Default :: default ( ) ,
149- } ,
150- }
116+ Self :: new_with_checkbox ( checkbox:: Checkbox :: new_with_checked ( items) )
151117 }
152118
153119 /// Sets the title text displayed above the checkbox list.
@@ -193,8 +159,24 @@ impl Checkbox {
193159 }
194160
195161 /// Sets the evaluator function for handling input events.
196- pub fn evaluator ( mut self , evaluator : Evaluator ) -> Self {
197- self . evaluator_fn = evaluator;
162+ pub fn evaluator ( mut self , evaluator : Evaluator < Self > ) -> Self {
163+ self . evaluator = evaluator;
198164 self
199165 }
166+
167+ /// Render the prompt with the specified width and height.
168+ async fn render ( & mut self , width : u16 , height : u16 ) -> anyhow:: Result < ( ) > {
169+ match self . renderer . as_ref ( ) {
170+ Some ( renderer) => {
171+ renderer
172+ . update ( [
173+ ( Index :: Title , self . title . create_pane ( width, height) ) ,
174+ ( Index :: Checkbox , self . checkbox . create_pane ( width, height) ) ,
175+ ] )
176+ . render ( )
177+ . await
178+ }
179+ None => Err ( anyhow:: anyhow!( "Renderer not initialized" ) ) ,
180+ }
181+ }
200182}
0 commit comments