@@ -539,18 +539,10 @@ impl CreateDistroboxDialog {
539539 child. set_is_downloaded ( is_downloaded) ;
540540 } ) ;
541541
542- let list_view = gtk:: ListView :: new ( Some ( selection_model) , Some ( factory) ) ;
542+ let list_view = gtk:: ListView :: new ( Some ( selection_model. clone ( ) ) , Some ( factory) ) ;
543543 list_view. add_css_class ( "navigation-sidebar" ) ;
544544 list_view. set_single_click_activate ( true ) ;
545545
546- let scrolled_window = gtk:: ScrolledWindow :: new ( ) ;
547- scrolled_window. set_child ( Some ( & list_view) ) ;
548- scrolled_window. set_vexpand ( true ) ;
549-
550- let stack = gtk:: Stack :: new ( ) ;
551- stack. add_named ( & scrolled_window, Some ( "list" ) ) ;
552-
553- let empty_page = gtk:: Box :: new ( gtk:: Orientation :: Vertical , 4 ) ;
554546
555547 let custom_list = gtk:: ListBox :: new ( ) ;
556548 custom_list. add_css_class ( "navigation-sidebar" ) ;
@@ -561,25 +553,23 @@ impl CreateDistroboxDialog {
561553
562554 custom_list. append ( & custom_row_item) ;
563555
564- empty_page. append ( & custom_list) ;
565- stack. add_named ( & empty_page, Some ( "empty" ) ) ;
556+ let custom_label = gtk:: Label :: new ( Some ( "Custom" ) ) ;
557+ custom_label. add_css_class ( "heading" ) ;
558+ custom_label. set_halign ( gtk:: Align :: Start ) ;
559+ custom_label. set_margin_start ( 12 ) ;
560+ custom_label. set_margin_top ( 12 ) ;
566561
567- view. set_content ( Some ( & stack) ) ;
562+ // Create a box to hold both the list view and custom list
563+ let content_box = gtk:: Box :: new ( gtk:: Orientation :: Vertical , 0 ) ;
564+ content_box. append ( & list_view) ;
565+ content_box. append ( & custom_label) ;
566+ content_box. append ( & custom_list) ;
568567
569- // Handle empty state
570- let stack_clone = stack. clone ( ) ;
571- filter_model. connect_items_changed ( move |model, _, _, _| {
572- if model. n_items ( ) > 0 {
573- stack_clone. set_visible_child_name ( "list" ) ;
574- } else {
575- stack_clone. set_visible_child_name ( "empty" ) ;
576- }
577- } ) ;
568+ let scrolled_window = gtk:: ScrolledWindow :: new ( ) ;
569+ scrolled_window. set_child ( Some ( & content_box) ) ;
570+ scrolled_window. set_vexpand ( true ) ;
578571
579- // Initial state check
580- if filter_model. n_items ( ) == 0 {
581- stack. set_visible_child_name ( "empty" ) ;
582- }
572+ view. set_content ( Some ( & scrolled_window) ) ;
583573
584574 // Update custom row
585575 search_entry. connect_search_changed ( clone ! (
@@ -602,26 +592,69 @@ impl CreateDistroboxDialog {
602592 custom_list. set_sensitive ( false ) ;
603593 }
604594
605- // Handle custom image selection
606- custom_list. connect_row_activated ( clone ! (
595+ let handle_image_selected = clone ! (
596+ #[ weak( rename_to=this) ]
597+ self ,
598+ move |image: & str | {
599+ this. imp( ) . selected_image. replace( image. to_string( ) ) ;
600+ this. imp( ) . image_row. set_subtitle( image) ;
601+ this. imp( ) . navigation_view. pop( ) ;
602+ }
603+ ) ;
604+
605+ // Handle Enter key on search_entry to select first filtered image
606+ search_entry. connect_activate ( clone ! (
607+ #[ strong]
608+ handle_image_selected,
609+ #[ weak]
610+ list_view,
611+ #[ weak]
612+ selection_model,
613+ move |entry| {
614+ let text = entry. text( ) ;
615+ if text. is_empty( ) {
616+ return ;
617+ }
618+ if selection_model. n_items( ) > 0 {
619+ list_view. activate_action( "list.activate-item" , Some ( & glib:: Variant :: from( 0u32 ) ) ) . unwrap( ) ;
620+ } else {
621+ handle_image_selected( & entry. text( ) ) ;
622+ }
623+ }
624+ ) ) ;
625+
626+ // Handle Escape key to close the image selector
627+ let escape_key_controller = gtk:: EventControllerKey :: new ( ) ;
628+ escape_key_controller. connect_key_pressed ( clone ! (
607629 #[ weak( rename_to=this) ]
608630 self ,
631+ #[ upgrade_or]
632+ glib:: signal:: Propagation :: Stop ,
633+ move |_, key, _, _| {
634+ match key {
635+ gtk:: gdk:: Key :: Escape => {
636+ this. imp( ) . navigation_view. pop( ) ;
637+ glib:: signal:: Propagation :: Stop
638+ }
639+ _ => glib:: signal:: Propagation :: Proceed ,
640+ }
641+ }
642+ ) ) ;
643+ search_entry. add_controller ( escape_key_controller) ;
644+
645+ // Handle custom image selection
646+ custom_list. connect_row_activated ( clone ! (
609647 #[ weak]
610648 search_entry,
649+ #[ strong]
650+ handle_image_selected,
611651 move |_, _| {
612- let image = search_entry. text( ) ;
613- if !image. is_empty( ) {
614- this. imp( ) . selected_image. replace( image. to_string( ) ) ;
615- this. imp( ) . image_row. set_subtitle( & image) ;
616- this. imp( ) . navigation_view. pop( ) ;
617- }
652+ handle_image_selected( & search_entry. text( ) ) ;
618653 }
619654 ) ) ;
620655
621656 // Handle selection
622657 list_view. connect_activate ( clone ! (
623- #[ weak( rename_to=this) ]
624- self ,
625658 move |list_view, position| {
626659 let model = list_view. model( ) . unwrap( ) ; // SingleSelection
627660 let item = model
@@ -631,9 +664,7 @@ impl CreateDistroboxDialog {
631664 . unwrap( ) ;
632665 let image = item. string( ) ;
633666
634- this. imp( ) . selected_image. replace( image. to_string( ) ) ;
635- this. imp( ) . image_row. set_subtitle( & image) ;
636- this. imp( ) . navigation_view. pop( ) ;
667+ handle_image_selected( & image) ;
637668 }
638669 ) ) ;
639670
0 commit comments