88use std:: ops:: Range ;
99
1010use kas:: dir:: Down ;
11+ use kas:: view:: clerk:: { AsyncClerk , Changes , Clerk , Len , TokenChanges , TokenClerk } ;
1112use kas:: view:: filter:: { ContainsCaseInsensitive , Filter , FilterValue , KeystrokeGuard , SetFilter } ;
12- use kas:: view:: { DataChanges , DataClerk , DataLen , Driver , ListView , SelectionMsg , TokenChanges } ;
13- use kas:: widgets:: edit:: { EditBox , EditField , EditGuard } ;
14- use kas:: widgets:: { AccessLabel , Button , ScrollBars , Text } ;
13+ use kas:: view:: { Driver , ListView , SelectionMsg } ;
14+ use kas:: widgets:: { edit, AccessLabel , Button , EditBox , ScrollRegion , Text } ;
1515use kas:: { prelude:: * , TextOrSource } ;
1616
1717#[ derive( Clone , Debug ) ]
@@ -48,18 +48,24 @@ enum Control {
4848struct NameGuard {
4949 is_last : bool ,
5050}
51- impl EditGuard for NameGuard {
51+ impl edit :: EditGuard for NameGuard {
5252 type Data = Option < Entry > ;
5353
54- fn update ( edit : & mut EditField < Self > , cx : & mut ConfigCx , data : & Self :: Data ) {
54+ fn update ( & mut self , edit : & mut edit :: Editor , cx : & mut ConfigCx , data : & Self :: Data ) {
5555 if let Some ( entry) = data. as_ref ( ) {
56- let name = match edit . guard . is_last {
56+ let name = match self . is_last {
5757 false => & entry. first ,
5858 true => & entry. last ,
5959 } ;
6060 edit. set_str ( cx, name) ;
6161 }
62- edit. set_error_state ( cx, edit. as_str ( ) . is_empty ( ) ) ;
62+ if edit. as_str ( ) . is_empty ( ) {
63+ edit. set_error ( cx, None ) ;
64+ }
65+ }
66+
67+ fn focus_lost ( & mut self , _: & mut edit:: Editor , _: & mut EventCx < ' _ > , _: & Self :: Data ) {
68+ // Do nothing (the default impl calls Self::update)
6369 }
6470}
6571
@@ -124,20 +130,39 @@ struct EntriesClerk {
124130 filtered_entries : Vec < usize > ,
125131}
126132
127- impl DataClerk < usize > for EntriesClerk {
133+ impl EntriesClerk {
134+ /// Delete the entry at `index`; return an index of a nearby item
135+ fn delete ( & mut self , index : usize ) -> usize {
136+ self . entries [ index] = None ;
137+ for i in ( index + 1 ..self . entries . len ( ) ) . chain ( ( 0 ..index) . rev ( ) ) {
138+ if self . entries [ i] . is_some ( ) {
139+ return i;
140+ }
141+ }
142+ 0
143+ }
144+ }
145+
146+ impl Clerk < usize > for EntriesClerk {
128147 type Data = ContainsCaseInsensitive ;
129- type Key = usize ;
130148 type Item = Entry ;
131- type Token = usize ;
149+
150+ fn len ( & self , _: & Self :: Data , _: usize ) -> Len < usize > {
151+ Len :: Known ( self . filtered_entries . len ( ) )
152+ }
153+ }
154+
155+ impl AsyncClerk < usize > for EntriesClerk {
156+ type Key = usize ;
132157
133158 fn update (
134159 & mut self ,
135160 _: & mut ConfigCx ,
136161 _: Id ,
137162 _: Range < usize > ,
138163 filter : & Self :: Data ,
139- ) -> DataChanges < usize > {
140- // TODO(opt) determine when updates are a no-op and return DataChanges ::None
164+ ) -> Changes < usize > {
165+ // TODO(opt) determine when updates are a no-op and return Changes ::None
141166
142167 self . filtered_entries = self
143168 . entries
@@ -151,12 +176,12 @@ impl DataClerk<usize> for EntriesClerk {
151176 . map ( |( i, _) | i)
152177 . collect ( ) ;
153178
154- DataChanges :: Any
179+ Changes :: Any
155180 }
181+ }
156182
157- fn len ( & self , _: & Self :: Data , _: usize ) -> DataLen < usize > {
158- DataLen :: Known ( self . filtered_entries . len ( ) )
159- }
183+ impl TokenClerk < usize > for EntriesClerk {
184+ type Token = usize ;
160185
161186 fn update_token (
162187 & self ,
@@ -187,9 +212,10 @@ pub fn window() -> Window<()> {
187212 struct EntriesDriver ;
188213 impl Driver < usize , Entry > for EntriesDriver {
189214 type Widget = Text < Entry , String > ;
215+ const TAB_NAVIGABLE : bool = false ;
190216
191217 fn make ( & mut self , _: & usize ) -> Self :: Widget {
192- Text :: new ( Entry :: format)
218+ Text :: new_gen ( Entry :: format)
193219 }
194220
195221 fn navigable ( _: & Self :: Widget ) -> bool {
@@ -216,15 +242,15 @@ pub fn window() -> Window<()> {
216242 #[ layout( grid! {
217243 ( 0 , 0 ) => "Filter:" ,
218244 ( 1 , 0 ) => self . filter_field,
219- ( 0 ..2 , 1 ..3 ) => frame!( self . list) ,
245+ ( 0 ..= 1 , 1 ..= 2 ) => frame!( self . list) ,
220246 ( 3 , 1 ) => self . editor,
221- ( 0 ..4 , 3 ) => self . controls,
247+ ( 0 ..= 3 , 3 ) => self . controls,
222248 } ) ]
223249 struct {
224250 core: widget_core!( ) ,
225251 #[ widget( & ( ) ) ] filter_field: EditBox <KeystrokeGuard > = EditBox :: new( KeystrokeGuard ) ,
226- #[ widget( & self . filter) ] list: ScrollBars <EntriesView > =
227- ScrollBars :: new ( EntriesView :: new( clerk, EntriesDriver ) . with_selection_mode( kas:: view:: SelectionMode :: Single ) ) ,
252+ #[ widget( & self . filter) ] list: ScrollRegion <EntriesView > =
253+ ScrollRegion :: new_viewport ( EntriesView :: new( clerk, EntriesDriver ) . with_selection_mode( kas:: view:: SelectionMode :: Single ) ) ,
228254 #[ widget( & self . selected) ] editor: Editor = Editor :: default ( ) ,
229255 #[ widget( & self . selected) ] controls: Controls = Controls :: default ( ) ,
230256 filter: ContainsCaseInsensitive ,
@@ -251,7 +277,6 @@ pub fn window() -> Window<()> {
251277 if let Some ( item) = self . editor. make_item( ) {
252278 let index = self . list. inner( ) . clerk( ) . entries. len( ) ;
253279 self . list. inner_mut( ) . clerk_mut( ) . entries. push( Some ( item) ) ;
254- cx. update( self . list. as_node( & self . filter) ) ;
255280 self . list. inner_mut( ) . select( cx, index) ;
256281 self . selected = self . list. inner( ) . clerk( ) . entries. get( index) . cloned( ) . flatten( ) ;
257282 cx. update( self . as_node( & ( ) ) ) ;
@@ -261,15 +286,13 @@ pub fn window() -> Window<()> {
261286 if let Some ( index) = self . selected( ) {
262287 if let Some ( item) = self . editor. make_item( ) {
263288 self . list. inner_mut( ) . clerk_mut( ) . entries[ index] = Some ( item) ;
264- cx. update( self . list. as_node( & self . filter) ) ;
265289 cx. update( self . as_node( & ( ) ) ) ;
266290 }
267291 }
268292 }
269293 Control :: Delete => {
270294 if let Some ( index) = self . selected( ) {
271- self . list. inner_mut( ) . clerk_mut( ) . entries[ index] = None ;
272- cx. update( self . list. as_node( & self . filter) ) ;
295+ let index = self . list. inner_mut( ) . clerk_mut( ) . delete( index) ;
273296 self . list. inner_mut( ) . select( cx, index) ;
274297 self . selected = self . list. inner( ) . clerk( ) . entries. get( index) . cloned( ) . flatten( ) ;
275298 cx. update( self . as_node( & ( ) ) ) ;
0 commit comments