use std::cell::RefCell; use std::cmp::min; use std::rc::Rc; use super::*; use crate::window::popups; use adw::ResponseAppearance; use uuid::Uuid; pub(in crate::window) async fn select_device_config(main_window: &AudioDeviceManagerWindow) { let device_config_names = main_window.imp().state_manager.borrow_mut().get_device_config_names(); if device_config_names.is_empty() { popups::new_device_config_type::new_device_config_type(main_window).await; return } let cancel_response = "cancel"; let create_new_response = "create-new"; let duplicate_response = "duplicate"; let select_response = "select"; let dialog_body = gtk::Box::builder() .spacing(12) .orientation(gtk::Orientation::Vertical) .build(); let entry = gtk::Entry::builder() .placeholder_text("search") .activates_default(true) .hexpand(true) .build(); let device_configs_list = gtk::ListBox::builder() .css_classes(["boxed-list"]) .build(); let selected_config_id = Rc::new(RefCell::new(None)); let mut device_configs_list_len = 0; for device_config_row in build_device_config_rows(main_window, &selected_config_id) { device_configs_list_len += 1; device_configs_list.append(&device_config_row); } let dialog_body_clamp = adw::Clamp::builder() .maximum_size(400) .tightening_threshold(300) .child(&dialog_body) .build(); println!("{}", device_configs_list.height()); dialog_body.append(&entry); if device_configs_list_len > 3 { let device_configs_list_scrollable = gtk::ScrolledWindow::builder() .child(&device_configs_list) .vexpand(true) .build(); dialog_body.append(&device_configs_list_scrollable); } else { dialog_body.append(&device_configs_list); } // Create new dialog let dialog = adw::AlertDialog::builder() .heading("Select Configuration") .close_response(cancel_response) .default_response(select_response) .extra_child(&dialog_body_clamp) .height_request( min( min(809, main_window.height()), 383 + 55 * device_configs_list_len ) ) .width_request(min(500, main_window.width())) .build(); dialog.add_responses(&[(cancel_response, "Cancel"), (create_new_response, "Create New"), (duplicate_response, "Duplicate"), (select_response, "Select")]); // Make the dialog button insensitive initially dialog.set_response_enabled(select_response, false); dialog.set_response_appearance(select_response, ResponseAppearance::Suggested); dialog.set_response_enabled(duplicate_response, false); dialog.set_response_appearance(cancel_response, ResponseAppearance::Destructive); device_configs_list.connect_row_selected(clone!( #[weak] dialog, move |list_box, row_option| { match row_option { Some(row) => { dialog.set_response_enabled(select_response, true); dialog.set_response_enabled(duplicate_response, true); row.activate(); } None => { dialog.set_response_enabled(select_response, false); dialog.set_response_enabled(duplicate_response, false); } }; } )); let response = dialog.choose_future(main_window).await; // Return if the user chose 'cancel_response' if response == cancel_response { println!("Cancel"); return; } if response == create_new_response { popups::new_device_config_type::new_device_config_type(main_window).await; return; } let selected_row = device_configs_list.selected_row().unwrap(); let config_id = selected_config_id.borrow().clone().unwrap(); if response == duplicate_response { let mut state_manager = main_window.imp().state_manager.borrow_mut(); let config_name = state_manager.get_device_config_name(&config_id); let properties = state_manager.get_device_config_properties(&config_id).clone(); let profiles = state_manager.get_device_config_profiles(&config_id).clone(); let selected_profile = state_manager.get_device_config_selected_profile(&config_id).clone(); drop(state_manager); popups::new_device_config::new_device_config( main_window, Some(config_name), properties, profiles, selected_profile ).await; return; } if response == select_response { main_window.add_device_config(config_id); return; } } fn build_device_config_rows( main_window: &AudioDeviceManagerWindow, selected_config_id: &Rc>>, ) -> Vec { let mut row_vec = Vec::new(); let mut device_names: Vec<_> = main_window.imp().state_manager.borrow_mut() .get_device_config_names() .into_iter() .collect(); device_names.sort_by(|(_, v1), (_, v2)| v1.cmp(v2)); for (config_id, config_name) in device_names { let row = adw::ActionRow::builder() .title(config_name.clone()) .build(); row.connect_activate(clone!( #[weak] selected_config_id, move |row| { *selected_config_id.borrow_mut() = Some(config_id.clone()); } ) ); row_vec.push( row ); } row_vec }