131 lines
4.5 KiB
Rust
131 lines
4.5 KiB
Rust
use std::cell::Ref;
|
|
|
|
use diesel::{
|
|
r2d2::{ConnectionManager, Pool},
|
|
SqliteConnection,
|
|
};
|
|
use gtk::{glib::BoxedAnyObject, prelude::*};
|
|
use relm4::prelude::*;
|
|
use sample_amp::{add_sample, list_samples, models::Sample};
|
|
|
|
#[derive(Debug)]
|
|
pub struct SampleListMsg {}
|
|
|
|
pub struct SampleListModel {
|
|
pool: Pool<ConnectionManager<SqliteConnection>>,
|
|
samples: gtk::MultiSelection,
|
|
}
|
|
|
|
#[relm4::component(pub)]
|
|
impl SimpleComponent for SampleListModel {
|
|
type Input = SampleListMsg;
|
|
|
|
type Output = ();
|
|
type Init = Pool<ConnectionManager<SqliteConnection>>;
|
|
|
|
view! {
|
|
#[root]
|
|
gtk::ScrolledWindow {
|
|
set_vexpand: true,
|
|
set_css_classes: &["sample-list-view"],
|
|
add_controller: drop_target,
|
|
gtk::ColumnView {
|
|
set_model: Some(&model.samples),
|
|
append_column = >k::ColumnViewColumn {
|
|
set_title: Some("Name"),
|
|
set_resizable: true,
|
|
set_expand: true,
|
|
set_factory: Some(&factory_name)
|
|
},
|
|
append_column = >k::ColumnViewColumn {
|
|
set_title: Some("BPM"),
|
|
set_factory: Some(&factory_bpm)
|
|
},
|
|
append_column = >k::ColumnViewColumn {
|
|
set_title: Some("Key"),
|
|
set_factory: Some(&factory_key)
|
|
},
|
|
append_column = >k::ColumnViewColumn {
|
|
set_title: Some("Tags"),
|
|
set_resizable: true,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn init(
|
|
pool: Self::Init,
|
|
window: &Self::Root,
|
|
_sender: ComponentSender<Self>,
|
|
) -> relm4::ComponentParts<Self> {
|
|
let factory_name = gtk::SignalListItemFactory::new();
|
|
factory_name.connect_bind(move |_factory, item| {
|
|
let item = item.downcast_ref::<gtk::ListItem>().unwrap();
|
|
let obj = item.item().and_downcast::<BoxedAnyObject>().unwrap();
|
|
let sample: Ref<Sample> = obj.borrow();
|
|
let cell = gtk::Label::new(Some(&sample.name.to_string()));
|
|
cell.set_halign(gtk::Align::Start);
|
|
item.set_child(Some(&cell))
|
|
});
|
|
|
|
let factory_bpm = gtk::SignalListItemFactory::new();
|
|
factory_bpm.connect_bind(move |_factory, item| {
|
|
let item = item.downcast_ref::<gtk::ListItem>().unwrap();
|
|
let obj = item.item().and_downcast::<BoxedAnyObject>().unwrap();
|
|
let sample: Ref<Sample> = obj.borrow();
|
|
let cell = gtk::Label::new(Some(&sample.bpm.map_or("".to_string(), |b| b.to_string())));
|
|
cell.set_halign(gtk::Align::End);
|
|
item.set_child(Some(&cell))
|
|
});
|
|
|
|
let factory_key = gtk::SignalListItemFactory::new();
|
|
factory_key.connect_bind(move |_factory, item| {
|
|
let item = item.downcast_ref::<gtk::ListItem>().unwrap();
|
|
let obj = item.item().and_downcast::<BoxedAnyObject>().unwrap();
|
|
let sample: Ref<Sample> = obj.borrow();
|
|
let cell = gtk::Label::new(Some(sample.key.as_ref().unwrap_or(&"".to_string())));
|
|
cell.set_halign(gtk::Align::Start);
|
|
item.set_child(Some(&cell))
|
|
});
|
|
|
|
let mut list_store = gtk::gio::ListStore::new(gtk::glib::types::Type::OBJECT);
|
|
let samples = gtk::MultiSelection::new(None::<gtk::gio::ListStore>);
|
|
samples.set_model(Some(&list_store));
|
|
|
|
list_store.extend(
|
|
list_samples(&mut pool.get().expect("Expected a connection"))
|
|
.into_iter()
|
|
.map(BoxedAnyObject::new),
|
|
);
|
|
|
|
let drop_pool = pool.clone();
|
|
|
|
let drop_target = gtk::DropTarget::new(
|
|
gtk::gdk::FileList::static_type(),
|
|
gtk::gdk::DragAction::COPY,
|
|
);
|
|
|
|
drop_target.connect_drop(move |_, value, _, _| {
|
|
for f in value
|
|
.get::<gtk::gdk::FileList>()
|
|
.expect("File list drop")
|
|
.files()
|
|
{
|
|
let (sample, _) = add_sample(
|
|
&mut drop_pool.get().expect("Expected connection"),
|
|
&f.path().expect("expected path"),
|
|
std::iter::empty(),
|
|
);
|
|
list_store.append(&BoxedAnyObject::new(sample));
|
|
dbg!(f.path());
|
|
}
|
|
true
|
|
});
|
|
|
|
let model = SampleListModel { pool, samples };
|
|
|
|
let widgets = view_output!();
|
|
ComponentParts { model, widgets }
|
|
}
|
|
}
|