musicus/musicus/src/import/track_selector.rs

97 lines
2.9 KiB
Rust
Raw Normal View History

2021-02-03 14:09:17 +01:00
use crate::navigator::{NavigationHandle, Screen};
use crate::widgets::Widget;
use adw::prelude::*;
2021-01-13 19:27:22 +01:00
use glib::clone;
use gtk::prelude::*;
use gtk_macros::get_widget;
use musicus_backend::import::ImportSession;
2021-01-13 19:27:22 +01:00
use std::cell::RefCell;
use std::rc::Rc;
use std::sync::Arc;
2021-01-13 19:27:22 +01:00
/// A screen for selecting tracks from a source.
2021-01-13 19:27:22 +01:00
pub struct TrackSelector {
2021-02-03 14:09:17 +01:00
handle: NavigationHandle<Vec<usize>>,
session: Arc<ImportSession>,
2021-01-13 19:27:22 +01:00
widget: gtk::Box,
select_button: gtk::Button,
selection: RefCell<Vec<usize>>,
}
impl Screen<Arc<ImportSession>, Vec<usize>> for TrackSelector {
2021-01-13 19:27:22 +01:00
/// Create a new track selector.
fn new(session: Arc<ImportSession>, handle: NavigationHandle<Vec<usize>>) -> Rc<Self> {
2021-01-13 19:27:22 +01:00
// Create UI
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/track_selector.ui");
get_widget!(builder, gtk::Box, widget);
get_widget!(builder, gtk::Button, back_button);
get_widget!(builder, gtk::Button, select_button);
get_widget!(builder, gtk::Frame, tracks_frame);
let track_list = gtk::ListBox::new();
track_list.set_selection_mode(gtk::SelectionMode::None);
track_list.set_vexpand(false);
track_list.show();
2021-01-25 14:00:57 +01:00
tracks_frame.set_child(Some(&track_list));
2021-01-13 19:27:22 +01:00
let this = Rc::new(Self {
2021-02-03 14:09:17 +01:00
handle,
session,
2021-01-13 19:27:22 +01:00
widget,
select_button,
selection: RefCell::new(Vec::new()),
});
// Connect signals and callbacks
2021-05-07 23:49:05 +02:00
back_button.connect_clicked(clone!(@weak this => move |_| {
2021-02-03 14:09:17 +01:00
this.handle.pop(None);
2021-01-13 19:27:22 +01:00
}));
2021-05-07 23:49:05 +02:00
this.select_button
.connect_clicked(clone!(@weak this => move |_| {
let selection = this.selection.borrow().clone();
this.handle.pop(Some(selection));
}));
2021-01-13 19:27:22 +01:00
let tracks = this.session.tracks();
for (index, track) in tracks.iter().enumerate() {
2021-01-13 19:27:22 +01:00
let check = gtk::CheckButton::new();
2021-05-07 23:49:05 +02:00
check.connect_toggled(clone!(@weak this => move |check| {
2021-01-13 19:27:22 +01:00
let mut selection = this.selection.borrow_mut();
2021-05-07 23:49:05 +02:00
if check.is_active() {
2021-01-13 19:27:22 +01:00
selection.push(index);
2021-05-08 00:06:01 +02:00
} else if let Some(pos) = selection.iter().position(|part| *part == index) {
selection.remove(pos);
2021-01-13 19:27:22 +01:00
}
if selection.is_empty() {
this.select_button.set_sensitive(false);
} else {
this.select_button.set_sensitive(true);
}
}));
let row = adw::ActionRow::new();
2021-01-13 19:27:22 +01:00
row.add_prefix(&check);
row.set_activatable_widget(Some(&check));
2021-01-25 14:00:57 +01:00
row.set_activatable(true);
2021-01-29 17:51:44 +01:00
row.set_title(Some(&track.name));
2021-01-13 19:27:22 +01:00
2021-01-25 14:00:57 +01:00
track_list.append(&row);
2021-01-13 19:27:22 +01:00
}
this
}
}
2021-02-03 14:09:17 +01:00
impl Widget for TrackSelector {
2021-01-13 19:27:22 +01:00
fn get_widget(&self) -> gtk::Widget {
self.widget.clone().upcast()
}
}