Move sample list to separate file

This commit is contained in:
Vivianne 2023-06-26 11:45:17 -07:00
parent 96bd4f8cab
commit f522b96116
3 changed files with 159 additions and 119 deletions

View file

@ -1,3 +1,6 @@
use itertools::Itertools;
use sample_amp::{establish_connection, list_tags};
fn main() {
let connection = &mut establish_connection();
println!(

View file

@ -1,11 +1,10 @@
use diesel::prelude::*;
use gtk::gdk::Display;
use gtk::glib::BoxedAnyObject;
use gtk::prelude::*;
use relm4::{factory::FactoryVecDeque, prelude::*};
use std::cell::Ref;
mod library_list;
mod sample_list;
use library_list::LibraryListItem;
mod app_msg;
use app_msg::AppMsg;
@ -13,24 +12,58 @@ use sample_amp::establish_connection;
use sample_amp::models::Library;
use sample_amp::schema::libraries;
use crate::sample_list::SampleListModel;
struct AppModel {
samples: gtk::MultiSelection,
sample_list: Controller<SampleListModel>,
libraries: FactoryVecDeque<LibraryListItem>,
connection: SqliteConnection,
}
struct Sample {
name: String,
bpm: f32,
key: String, // todo: key struct?
}
#[relm4::component]
impl SimpleComponent for AppModel {
type Input = AppMsg;
type Output = ();
type Init = ();
type Input = AppMsg;
type Output = ();
fn init(
_: Self::Init,
window: &Self::Root,
sender: ComponentSender<Self>,
) -> relm4::ComponentParts<Self> {
let mut model = AppModel {
connection: establish_connection(),
libraries: FactoryVecDeque::new(gtk::ListBox::default(), sender.input_sender()),
sample_list: SampleListModel::builder().launch(()).detach(),
};
let sample_view = model.sample_list.widget();
// todo: cleaner
let library_results = libraries::dsl::libraries
.select(Library::as_select())
.load(&mut model.connection)
.expect("Error loading libraries");
model.libraries.guard().push_back("All".to_string());
for lib in library_results {
model.libraries.guard().push_back(lib.name);
}
let library_view = model.libraries.widget();
let widgets = view_output!();
ComponentParts { model, widgets }
}
fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self>) {
match message {
AppMsg::Close => {
relm4::main_application().quit();
}
}
}
view! {
gtk::Window {
@ -56,31 +89,8 @@ impl SimpleComponent for AppModel {
set_orientation: gtk::Orientation::Vertical,
set_hexpand: true,
gtk::ScrolledWindow {
set_vexpand: true,
set_css_classes: &["sample-list-view"],
gtk::ColumnView {
set_model: Some(&model.samples),
append_column = &gtk::ColumnViewColumn {
set_title: Some("Name"),
set_resizable: true,
set_expand: true,
set_factory: Some(&factory_name)
},
append_column = &gtk::ColumnViewColumn {
set_title: Some("BPM"),
set_factory: Some(&factory_bpm)
},
append_column = &gtk::ColumnViewColumn {
set_title: Some("Key"),
set_factory: Some(&factory_key)
},
append_column = &gtk::ColumnViewColumn {
set_title: Some("Tags"),
set_resizable: true,
}
}
},
#[local_ref]
sample_view -> gtk::ScrolledWindow {},
gtk::Box {
set_height_request: 100,
@ -94,89 +104,6 @@ impl SimpleComponent for AppModel {
}
}
}
fn init(
_: 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.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.to_string()));
cell.set_halign(gtk::Align::Start);
item.set_child(Some(&cell))
});
let samples = gtk::gio::ListStore::new(gtk::glib::types::Type::OBJECT);
let sample_a = BoxedAnyObject::new(Sample {
name: "01 MOOLOO-108 bpm a.wav".to_string(),
bpm: 108.0,
key: "A".to_string(),
});
samples.append(&sample_a);
let sample_b = BoxedAnyObject::new(Sample {
name: "03 FAST AND FURIOUS-144.3 bpm a.wav".to_string(),
bpm: 144.3,
key: "A".to_string(),
});
samples.append(&sample_b);
let samples = gtk::MultiSelection::new(Some(samples));
let mut model = AppModel {
samples,
connection: establish_connection(),
libraries: FactoryVecDeque::new(gtk::ListBox::default(), sender.input_sender()),
};
// todo: cleaner
let library_results = libraries::dsl::libraries
.select(Library::as_select())
.load(&mut model.connection)
.expect("Error loading libraries");
model.libraries.guard().push_back("All".to_string());
for lib in library_results {
model.libraries.guard().push_back(lib.name);
}
let library_view = model.libraries.widget();
let widgets = view_output!();
ComponentParts { model, widgets }
}
fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self>) {
match message {
AppMsg::Close => {
relm4::main_application().quit();
}
}
}
}
fn load_css() {

110
src/sample_list.rs Normal file
View file

@ -0,0 +1,110 @@
use std::cell::Ref;
use gtk::{glib::BoxedAnyObject, prelude::*};
use relm4::prelude::*;
struct Sample {
name: String,
bpm: f32,
key: String, // todo: key struct?
}
#[derive(Debug)]
pub struct SampleListMsg {}
pub struct SampleListModel {
samples: gtk::MultiSelection,
}
#[relm4::component(pub)]
impl SimpleComponent for SampleListModel {
type Input = SampleListMsg;
type Output = ();
type Init = ();
view! {
#[root]
gtk::ScrolledWindow {
set_vexpand: true,
set_css_classes: &["sample-list-view"],
gtk::ColumnView {
set_model: Some(&model.samples),
append_column = &gtk::ColumnViewColumn {
set_title: Some("Name"),
set_resizable: true,
set_expand: true,
set_factory: Some(&factory_name)
},
append_column = &gtk::ColumnViewColumn {
set_title: Some("BPM"),
set_factory: Some(&factory_bpm)
},
append_column = &gtk::ColumnViewColumn {
set_title: Some("Key"),
set_factory: Some(&factory_key)
},
append_column = &gtk::ColumnViewColumn {
set_title: Some("Tags"),
set_resizable: true,
}
}
}
}
fn init(
_: 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.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.to_string()));
cell.set_halign(gtk::Align::Start);
item.set_child(Some(&cell))
});
let samples = gtk::gio::ListStore::new(gtk::glib::types::Type::OBJECT);
let sample_a = BoxedAnyObject::new(Sample {
name: "01 MOOLOO-108 bpm a.wav".to_string(),
bpm: 108.0,
key: "A".to_string(),
});
samples.append(&sample_a);
let sample_b = BoxedAnyObject::new(Sample {
name: "03 FAST AND FURIOUS-144.3 bpm a.wav".to_string(),
bpm: 144.3,
key: "A".to_string(),
});
samples.append(&sample_b);
let samples = gtk::MultiSelection::new(Some(samples));
let model = SampleListModel { samples };
let widgets = view_output!();
ComponentParts { model, widgets }
}
}