AudioDeviceManager/src/window/popups/select_device_config.rs
2025-11-07 23:29:58 +01:00

187 lines
5.6 KiB
Rust

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<RefCell<Option<Uuid>>>,
) -> Vec<adw::ActionRow> {
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
}